Merge pull request #6001 from haon4/sync201904090622

Down integrate to Github
This commit is contained in:
Hao Nguyen 2019-04-09 10:40:46 -07:00 committed by GitHub
commit 5b232b8ecb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
405 changed files with 58723 additions and 25969 deletions

6
BUILD
View File

@ -116,6 +116,7 @@ cc_library(
"src/google/protobuf/implicit_weak_message.cc",
"src/google/protobuf/io/coded_stream.cc",
"src/google/protobuf/io/strtod.cc",
"src/google/protobuf/io/io_win32.cc",
"src/google/protobuf/io/zero_copy_stream.cc",
"src/google/protobuf/io/zero_copy_stream_impl_lite.cc",
"src/google/protobuf/message_lite.cc",
@ -124,7 +125,6 @@ cc_library(
"src/google/protobuf/stubs/bytestream.cc",
"src/google/protobuf/stubs/common.cc",
"src/google/protobuf/stubs/int128.cc",
"src/google/protobuf/stubs/io_win32.cc",
"src/google/protobuf/stubs/status.cc",
"src/google/protobuf/stubs/statusor.cc",
"src/google/protobuf/stubs/stringpiece.cc",
@ -514,7 +514,7 @@ cc_binary(
cc_test(
name = "win32_test",
srcs = ["src/google/protobuf/stubs/io_win32_unittest.cc"],
srcs = ["src/google/protobuf/io/io_win32_unittest.cc"],
deps = [
":protobuf_lite",
"//external:gtest_main",
@ -553,6 +553,7 @@ cc_test(
"src/google/protobuf/extension_set_unittest.cc",
"src/google/protobuf/generated_message_reflection_unittest.cc",
"src/google/protobuf/io/coded_stream_unittest.cc",
"src/google/protobuf/io/io_win32_unittest.cc",
"src/google/protobuf/io/printer_unittest.cc",
"src/google/protobuf/io/tokenizer_unittest.cc",
"src/google/protobuf/io/zero_copy_stream_unittest.cc",
@ -572,7 +573,6 @@ cc_test(
"src/google/protobuf/stubs/bytestream_unittest.cc",
"src/google/protobuf/stubs/common_unittest.cc",
"src/google/protobuf/stubs/int128_unittest.cc",
"src/google/protobuf/stubs/io_win32_unittest.cc",
"src/google/protobuf/stubs/status_test.cc",
"src/google/protobuf/stubs/statusor_test.cc",
"src/google/protobuf/stubs/stringpiece_unittest.cc",

View File

@ -225,17 +225,25 @@ java_EXTRA_DIST=
java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java \
java/core/src/main/java/com/google/protobuf/AbstractParser.java \
java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java \
java/core/src/main/java/com/google/protobuf/AllocatedBuffer.java \
java/core/src/main/java/com/google/protobuf/Android.java \
java/core/src/main/java/com/google/protobuf/ArrayDecoders.java \
java/core/src/main/java/com/google/protobuf/BinaryReader.java \
java/core/src/main/java/com/google/protobuf/BinaryWriter.java \
java/core/src/main/java/com/google/protobuf/BlockingRpcChannel.java \
java/core/src/main/java/com/google/protobuf/BlockingService.java \
java/core/src/main/java/com/google/protobuf/BooleanArrayList.java \
java/core/src/main/java/com/google/protobuf/BufferAllocator.java \
java/core/src/main/java/com/google/protobuf/ByteBufferWriter.java \
java/core/src/main/java/com/google/protobuf/ByteOutput.java \
java/core/src/main/java/com/google/protobuf/ByteString.java \
java/core/src/main/java/com/google/protobuf/CodedInputStream.java \
java/core/src/main/java/com/google/protobuf/CodedInputStreamReader.java \
java/core/src/main/java/com/google/protobuf/CodedOutputStream.java \
java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java \
java/core/src/main/java/com/google/protobuf/CodedOutputStreamWriter.java \
java/core/src/main/java/com/google/protobuf/DescriptorMessageInfoFactory.java \
java/core/src/main/java/com/google/protobuf/Descriptors.java \
java/core/src/main/java/com/google/protobuf/DiscardUnknownFieldsParser.java \
java/core/src/main/java/com/google/protobuf/DoubleArrayList.java \
java/core/src/main/java/com/google/protobuf/DynamicMessage.java \
java/core/src/main/java/com/google/protobuf/ExperimentalApi.java \
@ -244,37 +252,65 @@ java_EXTRA_DIST=
java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java \
java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java \
java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java \
java/core/src/main/java/com/google/protobuf/ExtensionSchema.java \
java/core/src/main/java/com/google/protobuf/ExtensionSchemaFull.java \
java/core/src/main/java/com/google/protobuf/ExtensionSchemaLite.java \
java/core/src/main/java/com/google/protobuf/ExtensionSchemas.java \
java/core/src/main/java/com/google/protobuf/FieldInfo.java \
java/core/src/main/java/com/google/protobuf/FieldSet.java \
java/core/src/main/java/com/google/protobuf/FieldType.java \
java/core/src/main/java/com/google/protobuf/FloatArrayList.java \
java/core/src/main/java/com/google/protobuf/GeneratedMessage.java \
java/core/src/main/java/com/google/protobuf/GeneratedMessageInfoFactory.java \
java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java \
java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java \
java/core/src/main/java/com/google/protobuf/IntArrayList.java \
java/core/src/main/java/com/google/protobuf/Internal.java \
java/core/src/main/java/com/google/protobuf/InvalidProtocolBufferException.java \
java/core/src/main/java/com/google/protobuf/IterableByteBufferInputStream.java \
java/core/src/main/java/com/google/protobuf/JavaType.java \
java/core/src/main/java/com/google/protobuf/LazyField.java \
java/core/src/main/java/com/google/protobuf/LazyFieldLite.java \
java/core/src/main/java/com/google/protobuf/LazyStringArrayList.java \
java/core/src/main/java/com/google/protobuf/LazyStringList.java \
java/core/src/main/java/com/google/protobuf/ListFieldSchema.java \
java/core/src/main/java/com/google/protobuf/LongArrayList.java \
java/core/src/main/java/com/google/protobuf/ManifestSchemaFactory.java \
java/core/src/main/java/com/google/protobuf/MapEntry.java \
java/core/src/main/java/com/google/protobuf/MapEntryLite.java \
java/core/src/main/java/com/google/protobuf/MapField.java \
java/core/src/main/java/com/google/protobuf/MapFieldLite.java \
java/core/src/main/java/com/google/protobuf/MapFieldSchema.java \
java/core/src/main/java/com/google/protobuf/MapFieldSchemaFull.java \
java/core/src/main/java/com/google/protobuf/MapFieldSchemaLite.java \
java/core/src/main/java/com/google/protobuf/MapFieldSchemas.java \
java/core/src/main/java/com/google/protobuf/Message.java \
java/core/src/main/java/com/google/protobuf/MessageInfo.java \
java/core/src/main/java/com/google/protobuf/MessageInfoFactory.java \
java/core/src/main/java/com/google/protobuf/MessageLite.java \
java/core/src/main/java/com/google/protobuf/MessageLiteOrBuilder.java \
java/core/src/main/java/com/google/protobuf/MessageLiteToString.java \
java/core/src/main/java/com/google/protobuf/MessageOrBuilder.java \
java/core/src/main/java/com/google/protobuf/MessageReflection.java \
java/core/src/main/java/com/google/protobuf/MessageSchema.java \
java/core/src/main/java/com/google/protobuf/MessageSetSchema.java \
java/core/src/main/java/com/google/protobuf/MutabilityOracle.java \
java/core/src/main/java/com/google/protobuf/NewInstanceSchema.java \
java/core/src/main/java/com/google/protobuf/NewInstanceSchemaFull.java \
java/core/src/main/java/com/google/protobuf/NewInstanceSchemaLite.java \
java/core/src/main/java/com/google/protobuf/NewInstanceSchemas.java \
java/core/src/main/java/com/google/protobuf/NioByteString.java \
java/core/src/main/java/com/google/protobuf/OneofInfo.java \
java/core/src/main/java/com/google/protobuf/Parser.java \
java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java \
java/core/src/main/java/com/google/protobuf/ProtoSyntax.java \
java/core/src/main/java/com/google/protobuf/Protobuf.java \
java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java \
java/core/src/main/java/com/google/protobuf/ProtobufLists.java \
java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java \
java/core/src/main/java/com/google/protobuf/ProtocolStringList.java \
java/core/src/main/java/com/google/protobuf/RawMessageInfo.java \
java/core/src/main/java/com/google/protobuf/Reader.java \
java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilder.java \
java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java \
java/core/src/main/java/com/google/protobuf/RopeByteString.java \
@ -282,30 +318,47 @@ java_EXTRA_DIST=
java/core/src/main/java/com/google/protobuf/RpcChannel.java \
java/core/src/main/java/com/google/protobuf/RpcController.java \
java/core/src/main/java/com/google/protobuf/RpcUtil.java \
java/core/src/main/java/com/google/protobuf/Schema.java \
java/core/src/main/java/com/google/protobuf/SchemaFactory.java \
java/core/src/main/java/com/google/protobuf/SchemaUtil.java \
java/core/src/main/java/com/google/protobuf/Service.java \
java/core/src/main/java/com/google/protobuf/ServiceException.java \
java/core/src/main/java/com/google/protobuf/SingleFieldBuilder.java \
java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java \
java/core/src/main/java/com/google/protobuf/SmallSortedMap.java \
java/core/src/main/java/com/google/protobuf/StructuralMessageInfo.java \
java/core/src/main/java/com/google/protobuf/TextFormat.java \
java/core/src/main/java/com/google/protobuf/TextFormatEscaper.java \
java/core/src/main/java/com/google/protobuf/TextFormatParseInfoTree.java \
java/core/src/main/java/com/google/protobuf/TextFormatParseLocation.java \
java/core/src/main/java/com/google/protobuf/UninitializedMessageException.java \
java/core/src/main/java/com/google/protobuf/UnknownFieldSchema.java \
java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java \
java/core/src/main/java/com/google/protobuf/UnknownFieldSetLite.java \
java/core/src/main/java/com/google/protobuf/UnknownFieldSetLiteSchema.java \
java/core/src/main/java/com/google/protobuf/UnknownFieldSetSchema.java \
java/core/src/main/java/com/google/protobuf/UnmodifiableLazyStringList.java \
java/core/src/main/java/com/google/protobuf/UnsafeByteOperations.java \
java/core/src/main/java/com/google/protobuf/UnsafeUtil.java \
java/core/src/main/java/com/google/protobuf/Utf8.java \
java/core/src/main/java/com/google/protobuf/WireFormat.java \
java/core/src/main/java/com/google/protobuf/Writer.java \
java/core/src/test/java/com/google/protobuf/AbstractMessageTest.java \
java/core/src/test/java/com/google/protobuf/AbstractProto2LiteSchemaTest.java \
java/core/src/test/java/com/google/protobuf/AbstractProto2SchemaTest.java \
java/core/src/test/java/com/google/protobuf/AbstractProto3LiteSchemaTest.java \
java/core/src/test/java/com/google/protobuf/AbstractProto3SchemaTest.java \
java/core/src/test/java/com/google/protobuf/AbstractSchemaTest.java \
java/core/src/test/java/com/google/protobuf/AnyTest.java \
java/core/src/test/java/com/google/protobuf/ArrayDecodersTest.java \
java/core/src/test/java/com/google/protobuf/BinaryProtocolTest.java \
java/core/src/test/java/com/google/protobuf/BooleanArrayListTest.java \
java/core/src/test/java/com/google/protobuf/BoundedByteStringTest.java \
java/core/src/test/java/com/google/protobuf/ByteBufferWriterTest.java \
java/core/src/test/java/com/google/protobuf/ByteStringTest.java \
java/core/src/test/java/com/google/protobuf/CachedFieldSizeTest.java \
java/core/src/test/java/com/google/protobuf/CheckUtf8Test.java \
java/core/src/test/java/com/google/protobuf/CodedAdapterTest.java \
java/core/src/test/java/com/google/protobuf/CodedInputStreamTest.java \
java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java \
java/core/src/test/java/com/google/protobuf/DecodeUtf8Test.java \
@ -315,6 +368,9 @@ java_EXTRA_DIST=
java/core/src/test/java/com/google/protobuf/DoubleArrayListTest.java \
java/core/src/test/java/com/google/protobuf/DynamicMessageTest.java \
java/core/src/test/java/com/google/protobuf/EnumTest.java \
java/core/src/test/java/com/google/protobuf/ExperimentalMessageFactory.java \
java/core/src/test/java/com/google/protobuf/ExperimentalSerializationUtil.java \
java/core/src/test/java/com/google/protobuf/ExperimentalTestDataProvider.java \
java/core/src/test/java/com/google/protobuf/ExtensionRegistryFactoryTest.java \
java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java \
java/core/src/test/java/com/google/protobuf/FloatArrayListTest.java \
@ -329,17 +385,32 @@ java_EXTRA_DIST=
java/core/src/test/java/com/google/protobuf/LazyStringArrayListTest.java \
java/core/src/test/java/com/google/protobuf/LazyStringEndToEndTest.java \
java/core/src/test/java/com/google/protobuf/LiteEqualsAndHashTest.java \
java/core/src/test/java/com/google/protobuf/LiteTest.java \
java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java \
java/core/src/test/java/com/google/protobuf/LongArrayListTest.java \
java/core/src/test/java/com/google/protobuf/MapForProto2LiteTest.java \
java/core/src/test/java/com/google/protobuf/MapForProto2Test.java \
java/core/src/test/java/com/google/protobuf/MapLiteTest.java \
java/core/src/test/java/com/google/protobuf/MapTest.java \
java/core/src/test/java/com/google/protobuf/MessageTest.java \
java/core/src/test/java/com/google/protobuf/NestedBuildersTest.java \
java/core/src/test/java/com/google/protobuf/NioByteStringTest.java \
java/core/src/test/java/com/google/protobuf/PackedFieldTest.java \
java/core/src/test/java/com/google/protobuf/ParseExceptionsTest.java \
java/core/src/test/java/com/google/protobuf/ParserLiteTest.java \
java/core/src/test/java/com/google/protobuf/ParserTest.java \
java/core/src/test/java/com/google/protobuf/Proto2ExtensionLookupSchemaTest.java \
java/core/src/test/java/com/google/protobuf/Proto2LiteSchemaTest.java \
java/core/src/test/java/com/google/protobuf/Proto2MessageFactory.java \
java/core/src/test/java/com/google/protobuf/Proto2MessageInfoFactory.java \
java/core/src/test/java/com/google/protobuf/Proto2MessageLiteFactory.java \
java/core/src/test/java/com/google/protobuf/Proto2SchemaTest.java \
java/core/src/test/java/com/google/protobuf/Proto2UnknownEnumValueTest.java \
java/core/src/test/java/com/google/protobuf/Proto3LiteSchemaTest.java \
java/core/src/test/java/com/google/protobuf/Proto3MessageFactory.java \
java/core/src/test/java/com/google/protobuf/Proto3MessageInfoFactory.java \
java/core/src/test/java/com/google/protobuf/Proto3MessageLiteFactory.java \
java/core/src/test/java/com/google/protobuf/Proto3MessageLiteInfoFactory.java \
java/core/src/test/java/com/google/protobuf/Proto3SchemaTest.java \
java/core/src/test/java/com/google/protobuf/ProtobufArrayListTest.java \
java/core/src/test/java/com/google/protobuf/RepeatedFieldBuilderV3Test.java \
java/core/src/test/java/com/google/protobuf/RopeByteStringSubstringTest.java \
@ -349,18 +420,25 @@ java_EXTRA_DIST=
java/core/src/test/java/com/google/protobuf/SmallSortedMapTest.java \
java/core/src/test/java/com/google/protobuf/TestBadIdentifiers.java \
java/core/src/test/java/com/google/protobuf/TestBadIdentifiersLite.java \
java/core/src/test/java/com/google/protobuf/TestSchemas.java \
java/core/src/test/java/com/google/protobuf/TestSchemasLite.java \
java/core/src/test/java/com/google/protobuf/TestUtil.java \
java/core/src/test/java/com/google/protobuf/TestUtilLite.java \
java/core/src/test/java/com/google/protobuf/TextFormatParseInfoTreeTest.java \
java/core/src/test/java/com/google/protobuf/TextFormatParseLocationTest.java \
java/core/src/test/java/com/google/protobuf/TextFormatTest.java \
java/core/src/test/java/com/google/protobuf/UnknownEnumValueTest.java \
java/core/src/test/java/com/google/protobuf/UnknownFieldSetLiteTest.java \
java/core/src/test/java/com/google/protobuf/UnknownFieldSetTest.java \
java/core/src/test/java/com/google/protobuf/UnmodifiableLazyStringListTest.java \
java/core/src/test/java/com/google/protobuf/Utf8Test.java \
java/core/src/test/java/com/google/protobuf/Utf8Utils.java \
java/core/src/test/java/com/google/protobuf/WellKnownTypesTest.java \
java/core/src/test/java/com/google/protobuf/WireFormatLiteTest.java \
java/core/src/test/java/com/google/protobuf/WireFormatTest.java \
java/core/src/test/java/com/google/protobuf/WrappersLiteOfMethodTest.java \
java/core/src/test/java/com/google/protobuf/WrappersOfMethodTest.java \
java/core/src/test/proto/com/google/protobuf/any_test.proto \
java/core/src/test/proto/com/google/protobuf/cached_field_size_test.proto \
java/core/src/test/proto/com/google/protobuf/deprecated_file.proto \
java/core/src/test/proto/com/google/protobuf/field_presence_test.proto \
java/core/src/test/proto/com/google/protobuf/lazy_fields_lite.proto \
@ -370,6 +448,7 @@ java_EXTRA_DIST=
java/core/src/test/proto/com/google/protobuf/map_initialization_order_test.proto \
java/core/src/test/proto/com/google/protobuf/map_lite_test.proto \
java/core/src/test/proto/com/google/protobuf/map_test.proto \
java/core/src/test/proto/com/google/protobuf/message_lite_extension_util_test.proto\
java/core/src/test/proto/com/google/protobuf/multiple_files_test.proto \
java/core/src/test/proto/com/google/protobuf/nested_builders_test.proto \
java/core/src/test/proto/com/google/protobuf/nested_extension.proto \
@ -379,13 +458,26 @@ java_EXTRA_DIST=
java/core/src/test/proto/com/google/protobuf/outer_class_name_test.proto \
java/core/src/test/proto/com/google/protobuf/outer_class_name_test2.proto \
java/core/src/test/proto/com/google/protobuf/outer_class_name_test3.proto \
java/core/src/test/proto/com/google/protobuf/packed_field_test.proto \
java/core/src/test/proto/com/google/protobuf/proto2_message.proto \
java/core/src/test/proto/com/google/protobuf/proto2_message_lite.proto \
java/core/src/test/proto/com/google/protobuf/proto2_unknown_enum_values.proto \
java/core/src/test/proto/com/google/protobuf/proto3_message.proto \
java/core/src/test/proto/com/google/protobuf/proto3_message_lite.proto \
java/core/src/test/proto/com/google/protobuf/test_bad_identifiers.proto \
java/core/src/test/proto/com/google/protobuf/test_check_utf8.proto \
java/core/src/test/proto/com/google/protobuf/test_check_utf8_size.proto \
java/core/src/test/proto/com/google/protobuf/test_custom_options.proto \
java/core/src/test/proto/com/google/protobuf/test_extra_interfaces.proto \
java/core/src/test/proto/com/google/protobuf/wrappers_test.proto \
java/lite.md \
java/lite/generate-sources-build.xml \
java/lite/generate-test-sources-build.xml \
java/lite/lite.awk \
java/lite/pom.xml \
java/lite/process-lite-sources-build.xml \
java/lite/src/test/java/com/google/protobuf/LiteTest.java \
java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java \
java/pom.xml \
java/util/pom.xml \
java/util/src/main/java/com/google/protobuf/util/Durations.java \
@ -812,6 +904,7 @@ python_EXTRA_DIST= \
python/google/protobuf/internal/import_test_package/inner.proto \
python/google/protobuf/internal/import_test_package/outer.proto \
python/google/protobuf/internal/json_format_test.py \
python/google/protobuf/internal/keywords_test.py \
python/google/protobuf/internal/message_factory_test.py \
python/google/protobuf/internal/message_listener.py \
python/google/protobuf/internal/message_set_extensions.proto \
@ -879,7 +972,6 @@ python_EXTRA_DIST= \
python/google/protobuf/pyext/repeated_scalar_container.h \
python/google/protobuf/pyext/safe_numerics.h \
python/google/protobuf/pyext/scoped_pyobject_ptr.h \
python/google/protobuf/pyext/thread_unsafe_shared_ptr.h \
python/google/protobuf/reflection.py \
python/google/protobuf/service.py \
python/google/protobuf/service_reflection.py \

View File

@ -6,6 +6,7 @@ set(libprotobuf_lite_files
${protobuf_source_dir}/src/google/protobuf/generated_message_util.cc
${protobuf_source_dir}/src/google/protobuf/implicit_weak_message.cc
${protobuf_source_dir}/src/google/protobuf/io/coded_stream.cc
${protobuf_source_dir}/src/google/protobuf/io/io_win32.cc
${protobuf_source_dir}/src/google/protobuf/io/strtod.cc
${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream.cc
${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@ -15,7 +16,6 @@ set(libprotobuf_lite_files
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream.cc
${protobuf_source_dir}/src/google/protobuf/stubs/common.cc
${protobuf_source_dir}/src/google/protobuf/stubs/int128.cc
${protobuf_source_dir}/src/google/protobuf/stubs/io_win32.cc
${protobuf_source_dir}/src/google/protobuf/stubs/status.cc
${protobuf_source_dir}/src/google/protobuf/stubs/statusor.cc
${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece.cc

View File

@ -156,6 +156,7 @@ set(tests_files
${protobuf_source_dir}/src/google/protobuf/extension_set_unittest.cc
${protobuf_source_dir}/src/google/protobuf/generated_message_reflection_unittest.cc
${protobuf_source_dir}/src/google/protobuf/io/coded_stream_unittest.cc
${protobuf_source_dir}/src/google/protobuf/io/io_win32_unittest.cc
${protobuf_source_dir}/src/google/protobuf/io/printer_unittest.cc
${protobuf_source_dir}/src/google/protobuf/io/tokenizer_unittest.cc
${protobuf_source_dir}/src/google/protobuf/io/zero_copy_stream_unittest.cc
@ -175,7 +176,6 @@ set(tests_files
${protobuf_source_dir}/src/google/protobuf/stubs/bytestream_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/common_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/int128_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/io_win32_unittest.cc
${protobuf_source_dir}/src/google/protobuf/stubs/status_test.cc
${protobuf_source_dir}/src/google/protobuf/stubs/statusor_test.cc
${protobuf_source_dir}/src/google/protobuf/stubs/stringpiece_unittest.cc

View File

@ -362,7 +362,7 @@ test_php_zts_c: protoc_middleman conformance-test-runner conformance-php-c $(oth
# These depend on library paths being properly set up. The easiest way to
# run them is to just use "tox" from the python dir.
test_python: protoc_middleman conformance-test-runner
./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt ./conformance_python.py
./conformance-test-runner --enforce_recommended --failure_list failure_list_python.txt --text_format_failure_list text_format_failure_list_python.txt ./conformance_python.py
test_python_cpp: protoc_middleman conformance-test-runner
./conformance-test-runner --enforce_recommended --failure_list failure_list_python_cpp.txt ./conformance_python.py

View File

@ -236,7 +236,7 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() {
RunValidTextFormatTest("FloatFieldWithVeryPreciseNumber", REQUIRED,
"optional_float: 3.123456789123456789");
RunValidTextFormatTest("FloatFieldMaxValue", REQUIRED,
"optional_float: 3.40282e+38");
"optional_float: 3.4028235e+38");
RunValidTextFormatTest("FloatFieldMinValue", REQUIRED,
"optional_float: 1.17549e-38");
RunValidTextFormatTest("FloatFieldNaNValue", REQUIRED,
@ -286,6 +286,31 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() {
message.add_repeated_int32(2);
message.add_repeated_int32(3);
RunValidUnknownTextFormatTest("RepeatedUnknownFields", message);
// Any fields
RunValidTextFormatTest("AnyField", REQUIRED,
R"(
optional_any: {
[type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3] {
optional_int32: 12345
}
}
)");
RunValidTextFormatTest("AnyFieldWithRawBytes", REQUIRED,
R"(
optional_any: {
type_url: "type.googleapis.com/protobuf_test_messages.proto3.TestAllTypesProto3"
value: "\b\271`"
}
)");
ExpectParseFailure("AnyFieldWithInvalidType", REQUIRED,
R"(
optional_any: {
[type.googleapis.com/unknown] {
optional_int32: 12345
}
}
)");
}
} // namespace protobuf

View File

@ -2,3 +2,5 @@ Recommended.Proto3.ProtobufInput.GroupUnknownFields_Drop.TextFormatOutput
Recommended.Proto3.ProtobufInput.MessageUnknownFields_Drop.TextFormatOutput
Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput
Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput
Required.Proto3.TextFormatInput.AnyField.ProtobufOutput
Required.Proto3.TextFormatInput.AnyField.TextFormatOutput

View File

@ -1,3 +1,5 @@
# This is the list of text format conformance tests that are known to fail right
# now.
# TODO: These should be fixed.
Required.Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput
Required.Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput

View File

@ -113,11 +113,13 @@ namespace Google.Protobuf.WellKnownTypes {
/// 01:30 UTC on January 15, 2017.
///
/// In JavaScript, one can convert a Date object to this format using the
/// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
/// standard
/// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
/// method. In Python, a standard `datetime.datetime` object can be converted
/// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
/// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
/// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
/// to this format using
/// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
/// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
/// the Joda Time's [`ISODateTimeFormat.dateTime()`](
/// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
/// ) to obtain a formatter capable of generating timestamps in this format.
/// </summary>

View File

@ -5,43 +5,56 @@
<arg value="--proto_path=${protobuf.source.dir}"/>
<arg value="--proto_path=${test.proto.dir}"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_proto3.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_custom_options.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_enormous_descriptor.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import_lite.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public_lite.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_lite.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_mset.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_mset_wire_format.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_optimize_for.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_custom_options.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_lite.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import_lite.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public_lite.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_lite_imports_nonlite.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_enormous_descriptor.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_no_generic_services.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_optimize_for.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_proto3.proto"/>
<arg value="${protobuf.source.dir}/google/protobuf/unittest_well_known_types.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/any_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/cached_field_size_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/deprecated_file.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/field_presence_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/lazy_fields_lite.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/lite_equals_and_hash.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_lite_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_initialization_order_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_lite_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/message_lite_extension_util_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/multiple_files_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/nested_builders_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/nested_extension.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/nested_extension_lite.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension_lite.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test2.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/outer_class_name_test3.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/packed_field_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/proto2_message.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/proto2_message_lite.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/proto2_unknown_enum_values.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/proto3_message.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/proto3_message_lite.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/test_bad_identifiers.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/test_check_utf8.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/test_check_utf8_size.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/test_custom_options.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/any_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/field_presence_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_lite_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_for_proto2_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_lite_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/map_initialization_order_test.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/wrappers_test.proto"/>
</exec>
<!-- Also generate some Lite protos needed for ExtensionRegistryFactoryTest -->
<exec executable="${protoc}">
<arg value="--java_out=lite:${generated.testsources.dir}"/>
<arg value="--proto_path=${protobuf.source.dir}"/>
<arg value="--proto_path=${test.proto.dir}"/>
<arg value="${test.proto.dir}/com/google/protobuf/nested_extension_lite.proto"/>
<arg value="${test.proto.dir}/com/google/protobuf/non_nested_extension_lite.proto"/>
</exec>
</project>

View File

@ -106,6 +106,56 @@ public abstract class AbstractMessageLite<
}
@ExperimentalApi
protected final boolean isInitializedInternal() {
return Protobuf.getInstance().schemaFor(this).isInitialized(this);
}
@ExperimentalApi
protected final int getSerializedSizeInternal() {
return Protobuf.getInstance().schemaFor(this).getSerializedSize(this);
}
int getSerializedSize(Schema schema) {
int memoizedSerializedSize = getMemoizedSerializedSize();
if (memoizedSerializedSize == -1) {
memoizedSerializedSize = schema.getSerializedSize(this);
setMemoizedSerializedSize(memoizedSerializedSize);
}
return memoizedSerializedSize;
}
@ExperimentalApi
protected final void writeToInternal(CodedOutputStream output) throws IOException {
Protobuf.getInstance()
.schemaFor(getClassInternal())
.writeTo(this, CodedOutputStreamWriter.forCodedOutput(output));
}
@ExperimentalApi
protected void mergeFromInternal(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
throws InvalidProtocolBufferException {
try {
Protobuf.getInstance()
.schemaFor(getClassInternal())
.mergeFrom(this, CodedInputStreamReader.forCodedInput(input), extensionRegistry);
} catch (InvalidProtocolBufferException e) {
throw e.setUnfinishedMessage(this);
} catch (IOException e) {
throw new InvalidProtocolBufferException(e).setUnfinishedMessage(this);
}
}
@ExperimentalApi
protected void makeImmutableInternal() {
Protobuf.getInstance().schemaFor(getClassInternal()).makeImmutable(this);
}
@SuppressWarnings("unchecked")
private Class<AbstractMessageLite<MessageType, BuilderType>> getClassInternal() {
return (Class<AbstractMessageLite<MessageType, BuilderType>>) getClass();
}
/** Package private helper method for AbstractParser to create UninitializedMessageException. */
UninitializedMessageException newUninitializedMessageException() {
return new UninitializedMessageException(this);

View File

@ -0,0 +1,263 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.Internal.checkNotNull;
import java.nio.ByteBuffer;
/**
* A buffer that was allocated by a {@link BufferAllocator}. For every buffer, it is guaranteed that
* at least one of {@link #hasArray()} or {@link #hasNioBuffer()} will be {@code true}.
*/
@ExperimentalApi
abstract class AllocatedBuffer {
/**
* Indicates whether this buffer contains a backing {@link ByteBuffer} (i.e. it is safe to call
* {@link #nioBuffer()}).
*/
public abstract boolean hasNioBuffer();
/**
* Indicates whether this buffer contains a backing array (i.e. it is safe to call {@link
* #array()}).
*/
public abstract boolean hasArray();
/**
* Returns the {@link ByteBuffer} that backs this buffer <i>(optional operation)</i>.
*
* <p>Call {@link #hasNioBuffer()} before invoking this method in order to ensure that this buffer
* has a backing {@link ByteBuffer}.
*
* @return The {@link ByteBuffer} that backs this buffer
* @throws UnsupportedOperationException If this buffer is not backed by a {@link ByteBuffer}.
*/
public abstract ByteBuffer nioBuffer();
/**
* Returns the byte array that backs this buffer <i>(optional operation)</i>.
*
* <p>Call {@link #hasArray()} before invoking this method in order to ensure that this buffer has
* an accessible backing array.
*
* @return The array that backs this buffer
* @throws java.nio.ReadOnlyBufferException If this buffer is backed by an array but is read-only
* @throws UnsupportedOperationException If this buffer is not backed by an accessible array
*/
public abstract byte[] array();
/**
* Returns the offset within this buffer's backing array of the first element of the buffer
* <i>(optional operation)</i>.
*
* <p>If this buffer is backed by an array then {@link #position()} corresponds to the array index
* {@link #position()} {@code +} {@link #arrayOffset()}.
*
* <p>Invoke the {@link #hasArray hasArray} method before invoking this method in order to ensure
* that this buffer has an accessible backing array.
*
* @return The offset within this buffer's array of the first element of the buffer
* @throws java.nio.ReadOnlyBufferException If this buffer is backed by an array but is read-only
* @throws UnsupportedOperationException If this buffer is not backed by an accessible array
*/
public abstract int arrayOffset();
/**
* Returns this buffer's position.
*
* @return The position of this buffer
*/
public abstract int position();
/**
* Sets this buffer's position.
*
* @param position The new position value; must be non-negative and no larger than the current
* limit
* @return This buffer
* @throws IllegalArgumentException If the preconditions on {@code position} do not hold
*/
public abstract AllocatedBuffer position(int position);
/**
* Returns this buffer's limit.
*
* @return The limit of this buffer
*/
public abstract int limit();
/**
* Returns the number of elements between the current {@link #position()} and the {@link #limit()}
* .
*
* @return The number of elements remaining in this buffer
*/
public abstract int remaining();
/**
* Creates a new {@link AllocatedBuffer} that is backed by the given array. The returned buffer
* will have {@link #hasArray} == {@code true}, {@link #arrayOffset()} == {@code 0}, {@link
* #position()} == {@code 0} and {@link #limit()} equal to the length of {@code bytes}.
*/
public static AllocatedBuffer wrap(byte[] bytes) {
return wrapNoCheck(bytes, 0, bytes.length);
}
/**
* Creates a new {@link AllocatedBuffer} that is backed by the given array. The returned buffer
* will have {@link #hasArray} == {@code true}, {@link #arrayOffset()} == {@code offset}, {@link
* #position()} == {@code 0} and {@link #limit()} == {@code length}.
*/
public static AllocatedBuffer wrap(final byte[] bytes, final int offset, final int length) {
if (offset < 0 || length < 0 || (offset + length) > bytes.length) {
throw new IndexOutOfBoundsException(
String.format("bytes.length=%d, offset=%d, length=%d", bytes.length, offset, length));
}
return wrapNoCheck(bytes, offset, length);
}
/**
* Creates a new {@link AllocatedBuffer} that is backed by the given {@link ByteBuffer}. The
* returned buffer will have {@link #hasNioBuffer} == {@code true}.
*/
public static AllocatedBuffer wrap(final ByteBuffer buffer) {
checkNotNull(buffer, "buffer");
return new AllocatedBuffer() {
@Override
public boolean hasNioBuffer() {
return true;
}
@Override
public ByteBuffer nioBuffer() {
return buffer;
}
@Override
public boolean hasArray() {
return buffer.hasArray();
}
@Override
public byte[] array() {
return buffer.array();
}
@Override
public int arrayOffset() {
return buffer.arrayOffset();
}
@Override
public int position() {
return buffer.position();
}
@Override
public AllocatedBuffer position(int position) {
buffer.position(position);
return this;
}
@Override
public int limit() {
return buffer.limit();
}
@Override
public int remaining() {
return buffer.remaining();
}
};
}
private static AllocatedBuffer wrapNoCheck(
final byte[] bytes, final int offset, final int length) {
return new AllocatedBuffer() {
// Relative to offset.
private int position;
@Override
public boolean hasNioBuffer() {
return false;
}
@Override
public ByteBuffer nioBuffer() {
throw new UnsupportedOperationException();
}
@Override
public boolean hasArray() {
return true;
}
@Override
public byte[] array() {
return bytes;
}
@Override
public int arrayOffset() {
return offset;
}
@Override
public int position() {
return position;
}
@Override
public AllocatedBuffer position(int position) {
if (position < 0 || position > length) {
throw new IllegalArgumentException("Invalid position: " + position);
}
this.position = position;
return this;
}
@Override
public int limit() {
// Relative to offset.
return length;
}
@Override
public int remaining() {
return length - position;
}
};
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,64 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.nio.ByteBuffer;
/**
* An object responsible for allocation of buffers. This is an extension point to enable buffer
* pooling within an application.
*/
@ExperimentalApi
abstract class BufferAllocator {
private static final BufferAllocator UNPOOLED =
new BufferAllocator() {
@Override
public AllocatedBuffer allocateHeapBuffer(int capacity) {
return AllocatedBuffer.wrap(new byte[capacity]);
}
@Override
public AllocatedBuffer allocateDirectBuffer(int capacity) {
return AllocatedBuffer.wrap(ByteBuffer.allocateDirect(capacity));
}
};
/** Returns an unpooled buffer allocator, which will create a new buffer for each request. */
public static BufferAllocator unpooled() {
return UNPOOLED;
}
/** Allocates a buffer with the given capacity that is backed by an array on the heap. */
public abstract AllocatedBuffer allocateHeapBuffer(int capacity);
/** Allocates a direct (i.e. non-heap) buffer with the given capacity. */
public abstract AllocatedBuffer allocateDirectBuffer(int capacity);
}

View File

@ -732,6 +732,16 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
*/
abstract void writeTo(ByteOutput byteOutput) throws IOException;
/**
* This method behaves exactly the same as {@link #writeTo(ByteOutput)} unless the {@link
* ByteString} is a rope. For ropes, the leaf nodes are written in reverse order to the {@code
* byteOutput}.
*
* @param byteOutput the output target to receive the bytes
* @throws IOException if an I/O error occurs
* @see UnsafeByteOperations#unsafeWriteToReverse(ByteString, ByteOutput)
*/
abstract void writeToReverse(ByteOutput byteOutput) throws IOException;
/**
* Constructs a read-only {@code java.nio.ByteBuffer} whose content is equal to the contents of
@ -862,6 +872,10 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
return true;
}
@Override
void writeToReverse(ByteOutput byteOutput) throws IOException {
writeTo(byteOutput);
}
/**
* Check equality of the substring of given length of this object starting at zero with another
@ -1438,14 +1452,16 @@ public abstract class ByteString implements Iterable<Byte>, Serializable {
LiteralByteString lbsOther = (LiteralByteString) other;
byte[] thisBytes = bytes;
byte[] otherBytes = lbsOther.bytes;
return UnsafeUtil.mismatch(
thisBytes,
getOffsetIntoBytes(),
otherBytes,
lbsOther.getOffsetIntoBytes() + offset,
length)
== -1;
int thisLimit = getOffsetIntoBytes() + length;
for (int thisIndex = getOffsetIntoBytes(),
otherIndex = lbsOther.getOffsetIntoBytes() + offset;
(thisIndex < thisLimit);
++thisIndex, ++otherIndex) {
if (thisBytes[thisIndex] != otherBytes[otherIndex]) {
return false;
}
}
return true;
}
return other.substring(offset, offset + length).equals(substring(0, length));

View File

@ -72,6 +72,9 @@ public abstract class CodedInputStream {
/** Visible for subclasses. See setSizeLimit() */
int sizeLimit = DEFAULT_SIZE_LIMIT;
/** Used to adapt to the experimental {@link Reader} interface. */
CodedInputStreamReader wrapper;
/** Create a new CodedInputStream wrapping the given InputStream. */
public static CodedInputStream newInstance(final InputStream input) {
return newInstance(input, DEFAULT_BUFFER_SIZE);
@ -2263,7 +2266,7 @@ public abstract class CodedInputStream {
return result;
}
// Slow path: Build a byte array first then copy it.
return new String(readRawBytesSlowPath(size), UTF_8);
return new String(readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false), UTF_8);
}
@Override
@ -2287,7 +2290,7 @@ public abstract class CodedInputStream {
pos = tempPos + size;
} else {
// Slow path: Build a byte array first then copy it.
bytes = readRawBytesSlowPath(size);
bytes = readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
tempPos = 0;
}
return Utf8.decodeUtf8(bytes, tempPos, size);
@ -2392,7 +2395,8 @@ public abstract class CodedInputStream {
return result;
} else {
// Slow path: Build a byte array first then copy it.
return readRawBytesSlowPath(size);
// TODO(dweis): Do we want to protect from malicious input streams here?
return readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
}
}
@ -2409,7 +2413,10 @@ public abstract class CodedInputStream {
return Internal.EMPTY_BYTE_BUFFER;
}
// Slow path: Build a byte array first then copy it.
return ByteBuffer.wrap(readRawBytesSlowPath(size));
// We must copy as the byte array was handed off to the InputStream and a malicious
// implementation could retain a reference.
return ByteBuffer.wrap(readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ true));
}
@Override
@ -2812,19 +2819,24 @@ public abstract class CodedInputStream {
pos = tempPos + size;
return Arrays.copyOfRange(buffer, tempPos, tempPos + size);
} else {
return readRawBytesSlowPath(size);
// TODO(dweis): Do we want to protect from malicious input streams here?
return readRawBytesSlowPath(size, /* ensureNoLeakedReferences= */ false);
}
}
/**
* Exactly like readRawBytes, but caller must have already checked the fast path: (size <=
* (bufferSize - pos) && size > 0)
*
* If ensureNoLeakedReferences is true, the value is guaranteed to have not escaped to
* untrusted code.
*/
private byte[] readRawBytesSlowPath(final int size) throws IOException {
private byte[] readRawBytesSlowPath(
final int size, boolean ensureNoLeakedReferences) throws IOException {
// Attempt to read the data in one byte array when it's safe to do.
byte[] result = readRawBytesSlowPathOneChunk(size);
if (result != null) {
return result;
return ensureNoLeakedReferences ? result.clone() : result;
}
final int originalBufferPos = pos;
@ -2862,6 +2874,8 @@ public abstract class CodedInputStream {
/**
* Attempts to read the data in one byte array when it's safe to do. Returns null if the size to
* read is too large and needs to be allocated in smaller chunks for security reasons.
*
* Returns a byte[] that may have escaped to user code via InputStream APIs.
*/
private byte[] readRawBytesSlowPathOneChunk(final int size) throws IOException {
if (size == 0) {
@ -2916,7 +2930,11 @@ public abstract class CodedInputStream {
return null;
}
/** Reads the remaining data in small chunks from the input stream. */
/**
* Reads the remaining data in small chunks from the input stream.
*
* Returns a byte[] that may have escaped to user code via InputStream APIs.
*/
private List<byte[]> readRawBytesSlowPathRemainingChunks(int sizeLeft) throws IOException {
// The size is very large. For security reasons, we can't allocate the
// entire byte array yet. The size comes directly from the input, so a
@ -2953,7 +2971,9 @@ public abstract class CodedInputStream {
private ByteString readBytesSlowPath(final int size) throws IOException {
final byte[] result = readRawBytesSlowPathOneChunk(size);
if (result != null) {
return ByteString.wrap(result);
// We must copy as the byte array was handed off to the InputStream and a malicious
// implementation could retain a reference.
return ByteString.copyFrom(result);
}
final int originalBufferPos = pos;
@ -2971,13 +2991,20 @@ public abstract class CodedInputStream {
// chunks.
List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);
// Wrap the byte arrays into a single ByteString.
List<ByteString> byteStrings = new ArrayList<ByteString>(1 + chunks.size());
byteStrings.add(ByteString.copyFrom(buffer, originalBufferPos, bufferedBytes));
for (byte[] chunk : chunks) {
byteStrings.add(ByteString.wrap(chunk));
// OK, got everything. Now concatenate it all into one buffer.
final byte[] bytes = new byte[size];
// Start by copying the leftover bytes from this.buffer.
System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
// And now all the chunks.
int tempPos = bufferedBytes;
for (final byte[] chunk : chunks) {
System.arraycopy(chunk, 0, bytes, tempPos, chunk.length);
tempPos += chunk.length;
}
return ByteString.copyFrom(byteStrings);
return ByteString.wrap(bytes);
}
@Override

File diff suppressed because it is too large Load Diff

View File

@ -60,6 +60,9 @@ public abstract class CodedOutputStream extends ByteOutput {
private static final Logger logger = Logger.getLogger(CodedOutputStream.class.getName());
private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = UnsafeUtil.hasUnsafeArrayOperations();
/** Used to adapt to the experimental {@link Writer} interface. */
CodedOutputStreamWriter wrapper;
/** @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead. */
@Deprecated public static final int LITTLE_ENDIAN_32_SIZE = FIXED32_SIZE;
@ -361,6 +364,10 @@ public abstract class CodedOutputStream extends ByteOutput {
public abstract void writeMessage(final int fieldNumber, final MessageLite value)
throws IOException;
/** Write an embedded message field, including tag, to the stream. */
// Abstract to avoid overhead of additional virtual method calls.
abstract void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
throws IOException;
/**
* Write a MessageSet extension field to the stream. For historical reasons, the wire format
@ -466,6 +473,9 @@ public abstract class CodedOutputStream extends ByteOutput {
// Abstract to avoid overhead of additional virtual method calls.
public abstract void writeMessageNoTag(final MessageLite value) throws IOException;
/** Write an embedded message field to the stream. */
// Abstract to avoid overhead of additional virtual method calls.
abstract void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException;
// =================================================================
@ -651,6 +661,14 @@ public abstract class CodedOutputStream extends ByteOutput {
return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value);
}
/**
* Compute the number of bytes that would be needed to encode an embedded message field, including
* tag.
*/
static int computeMessageSize(
final int fieldNumber, final MessageLite value, final Schema schema) {
return computeTagSize(fieldNumber) + computeMessageSizeNoTag(value, schema);
}
/**
* Compute the number of bytes that would be needed to encode a MessageSet extension to the
@ -859,6 +877,10 @@ public abstract class CodedOutputStream extends ByteOutput {
return computeLengthDelimitedFieldSize(value.getSerializedSize());
}
/** Compute the number of bytes that would be needed to encode an embedded message field. */
static int computeMessageSizeNoTag(final MessageLite value, final Schema schema) {
return computeLengthDelimitedFieldSize(((AbstractMessageLite) value).getSerializedSize(schema));
}
static int computeLengthDelimitedFieldSize(int fieldLength) {
return computeUInt32SizeNoTag(fieldLength) + fieldLength;
@ -993,6 +1015,18 @@ public abstract class CodedOutputStream extends ByteOutput {
writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
}
/**
* Write a {@code group} field, including tag, to the stream.
*
* @deprecated groups are deprecated.
*/
@Deprecated
final void writeGroup(final int fieldNumber, final MessageLite value, Schema schema)
throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
writeGroupNoTag(value, schema);
writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
}
/**
* Write a {@code group} field to the stream.
@ -1004,6 +1038,15 @@ public abstract class CodedOutputStream extends ByteOutput {
value.writeTo(this);
}
/**
* Write a {@code group} field to the stream.
*
* @deprecated groups are deprecated.
*/
@Deprecated
final void writeGroupNoTag(final MessageLite value, Schema schema) throws IOException {
schema.writeTo(value, wrapper);
}
/**
* Compute the number of bytes that would be needed to encode a {@code group} field, including
@ -1016,6 +1059,16 @@ public abstract class CodedOutputStream extends ByteOutput {
return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value);
}
/**
* Compute the number of bytes that would be needed to encode a {@code group} field, including
* tag.
*
* @deprecated groups are deprecated.
*/
@Deprecated
static int computeGroupSize(final int fieldNumber, final MessageLite value, Schema schema) {
return computeTagSize(fieldNumber) * 2 + computeGroupSizeNoTag(value, schema);
}
/** Compute the number of bytes that would be needed to encode a {@code group} field. */
@Deprecated
@ -1023,6 +1076,11 @@ public abstract class CodedOutputStream extends ByteOutput {
return value.getSerializedSize();
}
/** Compute the number of bytes that would be needed to encode a {@code group} field. */
@Deprecated
static int computeGroupSizeNoTag(final MessageLite value, Schema schema) {
return ((AbstractMessageLite) value).getSerializedSize(schema);
}
/**
* Encode and write a varint. {@code value} is treated as unsigned, so it won't be sign-extended
@ -1216,6 +1274,13 @@ public abstract class CodedOutputStream extends ByteOutput {
writeMessageNoTag(value);
}
@Override
final void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
schema.writeTo(value, wrapper);
}
@Override
public final void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
@ -1241,6 +1306,11 @@ public abstract class CodedOutputStream extends ByteOutput {
value.writeTo(this);
}
@Override
final void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException {
writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
schema.writeTo(value, wrapper);
}
@Override
public final void write(byte value) throws IOException {
@ -1571,6 +1641,12 @@ public abstract class CodedOutputStream extends ByteOutput {
writeMessageNoTag(value);
}
@Override
void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeMessageNoTag(value, schema);
}
@Override
public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
@ -1596,6 +1672,11 @@ public abstract class CodedOutputStream extends ByteOutput {
value.writeTo(this);
}
@Override
void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException {
writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
schema.writeTo(value, wrapper);
}
@Override
public void write(byte value) throws IOException {
@ -1893,6 +1974,11 @@ public abstract class CodedOutputStream extends ByteOutput {
writeMessageNoTag(value);
}
@Override
void writeMessage(int fieldNumber, MessageLite value, Schema schema) throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeMessageNoTag(value, schema);
}
@Override
public void writeMessageSetExtension(int fieldNumber, MessageLite value) throws IOException {
@ -1916,6 +2002,11 @@ public abstract class CodedOutputStream extends ByteOutput {
value.writeTo(this);
}
@Override
void writeMessageNoTag(MessageLite value, Schema schema) throws IOException {
writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
schema.writeTo(value, wrapper);
}
@Override
public void write(byte value) throws IOException {
@ -2419,6 +2510,12 @@ public abstract class CodedOutputStream extends ByteOutput {
writeMessageNoTag(value);
}
@Override
void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeMessageNoTag(value, schema);
}
@Override
public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
@ -2444,6 +2541,11 @@ public abstract class CodedOutputStream extends ByteOutput {
value.writeTo(this);
}
@Override
void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException {
writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
schema.writeTo(value, wrapper);
}
@Override
public void write(byte value) throws IOException {
@ -2722,6 +2824,12 @@ public abstract class CodedOutputStream extends ByteOutput {
writeMessageNoTag(value);
}
@Override
void writeMessage(final int fieldNumber, final MessageLite value, Schema schema)
throws IOException {
writeTag(fieldNumber, WireFormat.WIRETYPE_LENGTH_DELIMITED);
writeMessageNoTag(value, schema);
}
@Override
public void writeMessageSetExtension(final int fieldNumber, final MessageLite value)
@ -2747,6 +2855,11 @@ public abstract class CodedOutputStream extends ByteOutput {
value.writeTo(this);
}
@Override
void writeMessageNoTag(final MessageLite value, Schema schema) throws IOException {
writeUInt32NoTag(((AbstractMessageLite) value).getSerializedSize(schema));
schema.writeTo(value, wrapper);
}
@Override
public void write(byte value) throws IOException {

View File

@ -0,0 +1,691 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.Internal.checkNotNull;
import static com.google.protobuf.WireFormat.WIRETYPE_LENGTH_DELIMITED;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/** An adapter between the {@link Writer} interface and {@link CodedOutputStream}. */
@ExperimentalApi
final class CodedOutputStreamWriter implements Writer {
private final CodedOutputStream output;
public static CodedOutputStreamWriter forCodedOutput(CodedOutputStream output) {
if (output.wrapper != null) {
return output.wrapper;
}
return new CodedOutputStreamWriter(output);
}
private CodedOutputStreamWriter(CodedOutputStream output) {
this.output = checkNotNull(output, "output");
this.output.wrapper = this;
}
@Override
public FieldOrder fieldOrder() {
return FieldOrder.ASCENDING;
}
public int getTotalBytesWritten() {
return output.getTotalBytesWritten();
}
@Override
public void writeSFixed32(int fieldNumber, int value) throws IOException {
output.writeSFixed32(fieldNumber, value);
}
@Override
public void writeInt64(int fieldNumber, long value) throws IOException {
output.writeInt64(fieldNumber, value);
}
@Override
public void writeSFixed64(int fieldNumber, long value) throws IOException {
output.writeSFixed64(fieldNumber, value);
}
@Override
public void writeFloat(int fieldNumber, float value) throws IOException {
output.writeFloat(fieldNumber, value);
}
@Override
public void writeDouble(int fieldNumber, double value) throws IOException {
output.writeDouble(fieldNumber, value);
}
@Override
public void writeEnum(int fieldNumber, int value) throws IOException {
output.writeEnum(fieldNumber, value);
}
@Override
public void writeUInt64(int fieldNumber, long value) throws IOException {
output.writeUInt64(fieldNumber, value);
}
@Override
public void writeInt32(int fieldNumber, int value) throws IOException {
output.writeInt32(fieldNumber, value);
}
@Override
public void writeFixed64(int fieldNumber, long value) throws IOException {
output.writeFixed64(fieldNumber, value);
}
@Override
public void writeFixed32(int fieldNumber, int value) throws IOException {
output.writeFixed32(fieldNumber, value);
}
@Override
public void writeBool(int fieldNumber, boolean value) throws IOException {
output.writeBool(fieldNumber, value);
}
@Override
public void writeString(int fieldNumber, String value) throws IOException {
output.writeString(fieldNumber, value);
}
@Override
public void writeBytes(int fieldNumber, ByteString value) throws IOException {
output.writeBytes(fieldNumber, value);
}
@Override
public void writeUInt32(int fieldNumber, int value) throws IOException {
output.writeUInt32(fieldNumber, value);
}
@Override
public void writeSInt32(int fieldNumber, int value) throws IOException {
output.writeSInt32(fieldNumber, value);
}
@Override
public void writeSInt64(int fieldNumber, long value) throws IOException {
output.writeSInt64(fieldNumber, value);
}
@Override
public void writeMessage(int fieldNumber, Object value) throws IOException {
output.writeMessage(fieldNumber, (MessageLite) value);
}
@Override
public void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException {
output.writeMessage(fieldNumber, (MessageLite) value, schema);
}
@Override
public void writeGroup(int fieldNumber, Object value) throws IOException {
output.writeGroup(fieldNumber, (MessageLite) value);
}
@Override
public void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException {
output.writeGroup(fieldNumber, (MessageLite) value, schema);
}
@Override
public void writeStartGroup(int fieldNumber) throws IOException {
output.writeTag(fieldNumber, WireFormat.WIRETYPE_START_GROUP);
}
@Override
public void writeEndGroup(int fieldNumber) throws IOException {
output.writeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
}
@Override
public final void writeMessageSetItem(int fieldNumber, Object value) throws IOException {
if (value instanceof ByteString) {
output.writeRawMessageSetExtension(fieldNumber, (ByteString) value);
} else {
output.writeMessageSetExtension(fieldNumber, (MessageLite) value);
}
}
@Override
public void writeInt32List(int fieldNumber, List<Integer> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeInt32SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeInt32NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeInt32(fieldNumber, value.get(i));
}
}
}
@Override
public void writeFixed32List(int fieldNumber, List<Integer> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeFixed32SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeFixed32NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeFixed32(fieldNumber, value.get(i));
}
}
}
@Override
public void writeInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeInt64SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeInt64NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeInt64(fieldNumber, value.get(i));
}
}
}
@Override
public void writeUInt64List(int fieldNumber, List<Long> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeUInt64SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeUInt64NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeUInt64(fieldNumber, value.get(i));
}
}
}
@Override
public void writeFixed64List(int fieldNumber, List<Long> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeFixed64SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeFixed64NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeFixed64(fieldNumber, value.get(i));
}
}
}
@Override
public void writeFloatList(int fieldNumber, List<Float> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeFloatSizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeFloatNoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeFloat(fieldNumber, value.get(i));
}
}
}
@Override
public void writeDoubleList(int fieldNumber, List<Double> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeDoubleSizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeDoubleNoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeDouble(fieldNumber, value.get(i));
}
}
}
@Override
public void writeEnumList(int fieldNumber, List<Integer> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeEnumSizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeEnumNoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeEnum(fieldNumber, value.get(i));
}
}
}
@Override
public void writeBoolList(int fieldNumber, List<Boolean> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeBoolSizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeBoolNoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeBool(fieldNumber, value.get(i));
}
}
}
@Override
public void writeStringList(int fieldNumber, List<String> value) throws IOException {
if (value instanceof LazyStringList) {
final LazyStringList lazyList = (LazyStringList) value;
for (int i = 0; i < value.size(); ++i) {
writeLazyString(fieldNumber, lazyList.getRaw(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeString(fieldNumber, value.get(i));
}
}
}
private void writeLazyString(int fieldNumber, Object value) throws IOException {
if (value instanceof String) {
output.writeString(fieldNumber, (String) value);
} else {
output.writeBytes(fieldNumber, (ByteString) value);
}
}
@Override
public void writeBytesList(int fieldNumber, List<ByteString> value) throws IOException {
for (int i = 0; i < value.size(); ++i) {
output.writeBytes(fieldNumber, value.get(i));
}
}
@Override
public void writeUInt32List(int fieldNumber, List<Integer> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeUInt32SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeUInt32NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeUInt32(fieldNumber, value.get(i));
}
}
}
@Override
public void writeSFixed32List(int fieldNumber, List<Integer> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeSFixed32SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeSFixed32NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeSFixed32(fieldNumber, value.get(i));
}
}
}
@Override
public void writeSFixed64List(int fieldNumber, List<Long> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeSFixed64SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeSFixed64NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeSFixed64(fieldNumber, value.get(i));
}
}
}
@Override
public void writeSInt32List(int fieldNumber, List<Integer> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeSInt32SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeSInt32NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeSInt32(fieldNumber, value.get(i));
}
}
}
@Override
public void writeSInt64List(int fieldNumber, List<Long> value, boolean packed)
throws IOException {
if (packed) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
// Compute and write the length of the data.
int dataSize = 0;
for (int i = 0; i < value.size(); ++i) {
dataSize += CodedOutputStream.computeSInt64SizeNoTag(value.get(i));
}
output.writeUInt32NoTag(dataSize);
// Write the data itself, without any tags.
for (int i = 0; i < value.size(); ++i) {
output.writeSInt64NoTag(value.get(i));
}
} else {
for (int i = 0; i < value.size(); ++i) {
output.writeSInt64(fieldNumber, value.get(i));
}
}
}
@Override
public void writeMessageList(int fieldNumber, List<?> value) throws IOException {
for (int i = 0; i < value.size(); ++i) {
writeMessage(fieldNumber, value.get(i));
}
}
@Override
public void writeMessageList(int fieldNumber, List<?> value, Schema schema) throws IOException {
for (int i = 0; i < value.size(); ++i) {
writeMessage(fieldNumber, value.get(i), schema);
}
}
@Override
public void writeGroupList(int fieldNumber, List<?> value) throws IOException {
for (int i = 0; i < value.size(); ++i) {
writeGroup(fieldNumber, value.get(i));
}
}
@Override
public void writeGroupList(int fieldNumber, List<?> value, Schema schema) throws IOException {
for (int i = 0; i < value.size(); ++i) {
writeGroup(fieldNumber, value.get(i), schema);
}
}
@Override
public <K, V> void writeMap(int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map)
throws IOException {
if (output.isSerializationDeterministic()) {
writeDeterministicMap(fieldNumber, metadata, map);
return;
}
for (Map.Entry<K, V> entry : map.entrySet()) {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
output.writeUInt32NoTag(
MapEntryLite.computeSerializedSize(metadata, entry.getKey(), entry.getValue()));
MapEntryLite.writeTo(output, metadata, entry.getKey(), entry.getValue());
}
}
@SuppressWarnings("unchecked")
private <K, V> void writeDeterministicMap(
int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map) throws IOException {
switch (metadata.keyType) {
case BOOL:
V value;
if ((value = map.get(Boolean.FALSE)) != null) {
writeDeterministicBooleanMapEntry(
fieldNumber, /* key= */ false, value, (MapEntryLite.Metadata<Boolean, V>) metadata);
}
if ((value = map.get(Boolean.TRUE)) != null) {
writeDeterministicBooleanMapEntry(
fieldNumber, /* key= */ true, value, (MapEntryLite.Metadata<Boolean, V>) metadata);
}
break;
case FIXED32:
case INT32:
case SFIXED32:
case SINT32:
case UINT32:
writeDeterministicIntegerMap(
fieldNumber, (MapEntryLite.Metadata<Integer, V>) metadata, (Map<Integer, V>) map);
break;
case FIXED64:
case INT64:
case SFIXED64:
case SINT64:
case UINT64:
writeDeterministicLongMap(
fieldNumber, (MapEntryLite.Metadata<Long, V>) metadata, (Map<Long, V>) map);
break;
case STRING:
writeDeterministicStringMap(
fieldNumber, (MapEntryLite.Metadata<String, V>) metadata, (Map<String, V>) map);
break;
default:
throw new IllegalArgumentException("does not support key type: " + metadata.keyType);
}
}
private <V> void writeDeterministicBooleanMapEntry(
int fieldNumber, boolean key, V value, MapEntryLite.Metadata<Boolean, V> metadata)
throws IOException {
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value));
MapEntryLite.writeTo(output, metadata, key, value);
}
private <V> void writeDeterministicIntegerMap(
int fieldNumber, MapEntryLite.Metadata<Integer, V> metadata, Map<Integer, V> map)
throws IOException {
int[] keys = new int[map.size()];
int index = 0;
for (int k : map.keySet()) {
keys[index++] = k;
}
Arrays.sort(keys);
for (int key : keys) {
V value = map.get(key);
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value));
MapEntryLite.writeTo(output, metadata, key, value);
}
}
private <V> void writeDeterministicLongMap(
int fieldNumber, MapEntryLite.Metadata<Long, V> metadata, Map<Long, V> map)
throws IOException {
long[] keys = new long[map.size()];
int index = 0;
for (long k : map.keySet()) {
keys[index++] = k;
}
Arrays.sort(keys);
for (long key : keys) {
V value = map.get(key);
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value));
MapEntryLite.writeTo(output, metadata, key, value);
}
}
private <V> void writeDeterministicStringMap(
int fieldNumber, MapEntryLite.Metadata<String, V> metadata, Map<String, V> map)
throws IOException {
String[] keys = new String[map.size()];
int index = 0;
for (String k : map.keySet()) {
keys[index++] = k;
}
Arrays.sort(keys);
for (String key : keys) {
V value = map.get(key);
output.writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
output.writeUInt32NoTag(MapEntryLite.computeSerializedSize(metadata, key, value));
MapEntryLite.writeTo(output, metadata, key, value);
}
}
}

View File

@ -0,0 +1,690 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.FieldInfo.forField;
import static com.google.protobuf.FieldInfo.forFieldWithEnumVerifier;
import static com.google.protobuf.FieldInfo.forMapField;
import static com.google.protobuf.FieldInfo.forOneofMemberField;
import static com.google.protobuf.FieldInfo.forPackedField;
import static com.google.protobuf.FieldInfo.forPackedFieldWithEnumVerifier;
import static com.google.protobuf.FieldInfo.forProto2OptionalField;
import static com.google.protobuf.FieldInfo.forProto2RequiredField;
import static com.google.protobuf.FieldInfo.forRepeatedMessageField;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor.Type;
import com.google.protobuf.Descriptors.OneofDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.ConcurrentHashMap;
/** A factory for message info based on protobuf descriptors for a {@link GeneratedMessageV3}. */
@ExperimentalApi
final class DescriptorMessageInfoFactory implements MessageInfoFactory {
private static final String GET_DEFAULT_INSTANCE_METHOD_NAME = "getDefaultInstance";
private static final DescriptorMessageInfoFactory instance = new DescriptorMessageInfoFactory();
private static final Set<String> specialFieldNames =
new HashSet<>(Arrays.asList("cached_size", "serialized_size", "class"));
// Disallow construction - it's a singleton.
private DescriptorMessageInfoFactory() {}
public static DescriptorMessageInfoFactory getInstance() {
return instance;
}
@Override
public boolean isSupported(Class<?> messageType) {
return GeneratedMessageV3.class.isAssignableFrom(messageType);
}
@Override
public MessageInfo messageInfoFor(Class<?> messageType) {
if (!GeneratedMessageV3.class.isAssignableFrom(messageType)) {
throw new IllegalArgumentException("Unsupported message type: " + messageType.getName());
}
return convert(messageType, descriptorForType(messageType));
}
private static Message getDefaultInstance(Class<?> messageType) {
try {
Method method = messageType.getDeclaredMethod(GET_DEFAULT_INSTANCE_METHOD_NAME);
return (Message) method.invoke(null);
} catch (Exception e) {
throw new IllegalArgumentException(
"Unable to get default instance for message class " + messageType.getName(), e);
}
}
private static Descriptor descriptorForType(Class<?> messageType) {
return getDefaultInstance(messageType).getDescriptorForType();
}
private static MessageInfo convert(Class<?> messageType, Descriptor messageDescriptor) {
switch (messageDescriptor.getFile().getSyntax()) {
case PROTO2:
return convertProto2(messageType, messageDescriptor);
case PROTO3:
return convertProto3(messageType, messageDescriptor);
default:
throw new IllegalArgumentException(
"Unsupported syntax: " + messageDescriptor.getFile().getSyntax());
}
}
/**
* A helper class to determine whether a message type needs to implement {@code isInitialized()}.
*
* <p>If a message type doesn't have any required fields or extensions (directly and
* transitively), it doesn't need to implement isInitialized() and can always return true there.
* It's a bit tricky to determine whether a type has transitive required fields because protobuf
* allows cycle references within the same .proto file (e.g., message Foo has a Bar field, and
* message Bar has a Foo field). For that we use Tarjan's strongly connected components algorithm
* to classify messages into strongly connected groups. Messages in the same group are
* transitively including each other, so they should either all have transitive required fields
* (or extensions), or none have.
*
* <p>This class is thread-safe.
*/
static class IsInitializedCheckAnalyzer {
private final Map<Descriptor, Boolean> resultCache =
new ConcurrentHashMap<Descriptor, Boolean>();
// The following data members are part of Tarjan's SCC algorithm. See:
// https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
private int index = 0;
private final Stack<Node> stack = new Stack<Node>();
private final Map<Descriptor, Node> nodeCache = new HashMap<Descriptor, Node>();
public boolean needsIsInitializedCheck(Descriptor descriptor) {
Boolean cachedValue = resultCache.get(descriptor);
if (cachedValue != null) {
return cachedValue;
}
synchronized (this) {
// Double-check the cache because some other thread may have updated it while we
// were acquiring the lock.
cachedValue = resultCache.get(descriptor);
if (cachedValue != null) {
return cachedValue;
}
return dfs(descriptor).component.needsIsInitializedCheck;
}
}
private static class Node {
final Descriptor descriptor;
final int index;
int lowLink;
StronglyConnectedComponent component; // null if the node is still on stack.
Node(Descriptor descriptor, int index) {
this.descriptor = descriptor;
this.index = index;
this.lowLink = index;
this.component = null;
}
}
private static class StronglyConnectedComponent {
final List<Descriptor> messages = new ArrayList<Descriptor>();
boolean needsIsInitializedCheck = false;
}
private Node dfs(Descriptor descriptor) {
Node result = new Node(descriptor, index++);
stack.push(result);
nodeCache.put(descriptor, result);
// Recurse the fields / nodes in graph
for (FieldDescriptor field : descriptor.getFields()) {
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
Node child = nodeCache.get(field.getMessageType());
if (child == null) {
// Unexplored node
child = dfs(field.getMessageType());
result.lowLink = Math.min(result.lowLink, child.lowLink);
} else {
if (child.component == null) {
// Still in the stack so we found a back edge.
result.lowLink = Math.min(result.lowLink, child.lowLink);
}
}
}
}
if (result.index == result.lowLink) {
// This is the root of a strongly connected component.
StronglyConnectedComponent component = new StronglyConnectedComponent();
while (true) {
Node node = stack.pop();
node.component = component;
component.messages.add(node.descriptor);
if (node == result) {
break;
}
}
analyze(component);
}
return result;
}
// Determine whether messages in this SCC needs isInitialized check.
private void analyze(StronglyConnectedComponent component) {
boolean needsIsInitializedCheck = false;
loop:
for (Descriptor descriptor : component.messages) {
if (descriptor.isExtendable()) {
needsIsInitializedCheck = true;
break;
}
for (FieldDescriptor field : descriptor.getFields()) {
if (field.isRequired()) {
needsIsInitializedCheck = true;
break loop;
}
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
// Since we are analyzing the graph bottom-up, all referenced fields should either be
// in this same component or in a different already-analyzed component.
Node node = nodeCache.get(field.getMessageType());
if (node.component != component) {
if (node.component.needsIsInitializedCheck) {
needsIsInitializedCheck = true;
break loop;
}
}
}
}
}
component.needsIsInitializedCheck = needsIsInitializedCheck;
for (Descriptor descriptor : component.messages) {
resultCache.put(descriptor, component.needsIsInitializedCheck);
}
}
}
private static IsInitializedCheckAnalyzer isInitializedCheckAnalyzer =
new IsInitializedCheckAnalyzer();
private static boolean needsIsInitializedCheck(Descriptor descriptor) {
return isInitializedCheckAnalyzer.needsIsInitializedCheck(descriptor);
}
private static StructuralMessageInfo convertProto2(
Class<?> messageType, Descriptor messageDescriptor) {
List<FieldDescriptor> fieldDescriptors = messageDescriptor.getFields();
StructuralMessageInfo.Builder builder =
StructuralMessageInfo.newBuilder(fieldDescriptors.size());
builder.withDefaultInstance(getDefaultInstance(messageType));
builder.withSyntax(ProtoSyntax.PROTO2);
builder.withMessageSetWireFormat(messageDescriptor.getOptions().getMessageSetWireFormat());
OneofState oneofState = new OneofState();
int bitFieldIndex = 0;
int presenceMask = 1;
Field bitField = null;
// Fields in the descriptor are ordered by the index position in which they appear in the
// proto file. This is the same order used to determine the presence mask used in the
// bitFields. So to determine the appropriate presence mask to be used for a field, we simply
// need to shift the presence mask whenever a presence-checked field is encountered.
for (int i = 0; i < fieldDescriptors.size(); ++i) {
final FieldDescriptor fd = fieldDescriptors.get(i);
boolean enforceUtf8 = fd.getFile().getOptions().getJavaStringCheckUtf8();
Internal.EnumVerifier enumVerifier = null;
if (fd.getJavaType() == Descriptors.FieldDescriptor.JavaType.ENUM) {
enumVerifier =
new Internal.EnumVerifier() {
@Override
public boolean isInRange(int number) {
return fd.getEnumType().findValueByNumber(number) != null;
}
};
}
if (fd.getContainingOneof() != null) {
// Build a oneof member field.
builder.withField(buildOneofMember(messageType, fd, oneofState, enforceUtf8, enumVerifier));
} else {
Field field = field(messageType, fd);
int number = fd.getNumber();
FieldType type = getFieldType(fd);
if (fd.isMapField()) {
// Map field points to an auto-generated message entry type with the definition:
// message MapEntry {
// K key = 1;
// V value = 2;
// }
final FieldDescriptor valueField = fd.getMessageType().findFieldByNumber(2);
if (valueField.getJavaType() == Descriptors.FieldDescriptor.JavaType.ENUM) {
enumVerifier =
new Internal.EnumVerifier() {
@Override
public boolean isInRange(int number) {
return valueField.getEnumType().findValueByNumber(number) != null;
}
};
}
builder.withField(
forMapField(
field,
number,
SchemaUtil.getMapDefaultEntry(messageType, fd.getName()),
enumVerifier));
continue;
}
if (fd.isRepeated()) {
// Repeated fields are not presence-checked.
if (enumVerifier != null) {
if (fd.isPacked()) {
builder.withField(
forPackedFieldWithEnumVerifier(
field, number, type, enumVerifier, cachedSizeField(messageType, fd)));
} else {
builder.withField(forFieldWithEnumVerifier(field, number, type, enumVerifier));
}
} else if (fd.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
builder.withField(
forRepeatedMessageField(
field, number, type, getTypeForRepeatedMessageField(messageType, fd)));
} else {
if (fd.isPacked()) {
builder.withField(
forPackedField(field, number, type, cachedSizeField(messageType, fd)));
} else {
builder.withField(forField(field, number, type, enforceUtf8));
}
}
continue;
}
if (bitField == null) {
// Lazy-create the next bitfield since we know it must exist.
bitField = bitField(messageType, bitFieldIndex);
}
// It's a presence-checked field.
if (fd.isRequired()) {
builder.withField(
forProto2RequiredField(
field, number, type, bitField, presenceMask, enforceUtf8, enumVerifier));
} else {
builder.withField(
forProto2OptionalField(
field, number, type, bitField, presenceMask, enforceUtf8, enumVerifier));
}
}
// Update the presence mask for the next iteration. If the shift clears out the mask, we will
// go to the next bitField.
presenceMask <<= 1;
if (presenceMask == 0) {
bitField = null;
presenceMask = 1;
bitFieldIndex++;
}
}
List<Integer> fieldsToCheckIsInitialized = new ArrayList<Integer>();
for (int i = 0; i < fieldDescriptors.size(); ++i) {
FieldDescriptor fd = fieldDescriptors.get(i);
if (fd.isRequired()
|| (fd.getJavaType() == FieldDescriptor.JavaType.MESSAGE
&& needsIsInitializedCheck(fd.getMessageType()))) {
fieldsToCheckIsInitialized.add(fd.getNumber());
}
}
int[] numbers = new int[fieldsToCheckIsInitialized.size()];
for (int i = 0; i < fieldsToCheckIsInitialized.size(); i++) {
numbers[i] = fieldsToCheckIsInitialized.get(i);
}
builder.withCheckInitialized(numbers);
return builder.build();
}
private static StructuralMessageInfo convertProto3(
Class<?> messageType, Descriptor messageDescriptor) {
List<FieldDescriptor> fieldDescriptors = messageDescriptor.getFields();
StructuralMessageInfo.Builder builder =
StructuralMessageInfo.newBuilder(fieldDescriptors.size());
builder.withDefaultInstance(getDefaultInstance(messageType));
builder.withSyntax(ProtoSyntax.PROTO3);
OneofState oneofState = new OneofState();
boolean enforceUtf8 = true;
for (int i = 0; i < fieldDescriptors.size(); ++i) {
FieldDescriptor fd = fieldDescriptors.get(i);
if (fd.getContainingOneof() != null) {
// Build a oneof member field.
builder.withField(buildOneofMember(messageType, fd, oneofState, enforceUtf8, null));
continue;
}
if (fd.isMapField()) {
builder.withField(
forMapField(
field(messageType, fd),
fd.getNumber(),
SchemaUtil.getMapDefaultEntry(messageType, fd.getName()),
null));
continue;
}
if (fd.isRepeated() && fd.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
builder.withField(
forRepeatedMessageField(
field(messageType, fd),
fd.getNumber(),
getFieldType(fd),
getTypeForRepeatedMessageField(messageType, fd)));
continue;
}
if (fd.isPacked()) {
builder.withField(
forPackedField(
field(messageType, fd),
fd.getNumber(),
getFieldType(fd),
cachedSizeField(messageType, fd)));
} else {
builder.withField(
forField(field(messageType, fd), fd.getNumber(), getFieldType(fd), enforceUtf8));
}
}
return builder.build();
}
/** Builds info for a oneof member field. */
private static FieldInfo buildOneofMember(
Class<?> messageType,
FieldDescriptor fd,
OneofState oneofState,
boolean enforceUtf8,
Internal.EnumVerifier enumVerifier) {
OneofInfo oneof = oneofState.getOneof(messageType, fd.getContainingOneof());
FieldType type = getFieldType(fd);
Class<?> oneofStoredType = getOneofStoredType(messageType, fd, type);
return forOneofMemberField(
fd.getNumber(), type, oneof, oneofStoredType, enforceUtf8, enumVerifier);
}
private static Class<?> getOneofStoredType(
Class<?> messageType, FieldDescriptor fd, FieldType type) {
switch (type.getJavaType()) {
case BOOLEAN:
return Boolean.class;
case BYTE_STRING:
return ByteString.class;
case DOUBLE:
return Double.class;
case FLOAT:
return Float.class;
case ENUM:
case INT:
return Integer.class;
case LONG:
return Long.class;
case STRING:
return String.class;
case MESSAGE:
return getOneofStoredTypeForMessage(messageType, fd);
default:
throw new IllegalArgumentException("Invalid type for oneof: " + type);
}
}
private static FieldType getFieldType(FieldDescriptor fd) {
switch (fd.getType()) {
case BOOL:
if (!fd.isRepeated()) {
return FieldType.BOOL;
}
return fd.isPacked() ? FieldType.BOOL_LIST_PACKED : FieldType.BOOL_LIST;
case BYTES:
return fd.isRepeated() ? FieldType.BYTES_LIST : FieldType.BYTES;
case DOUBLE:
if (!fd.isRepeated()) {
return FieldType.DOUBLE;
}
return fd.isPacked() ? FieldType.DOUBLE_LIST_PACKED : FieldType.DOUBLE_LIST;
case ENUM:
if (!fd.isRepeated()) {
return FieldType.ENUM;
}
return fd.isPacked() ? FieldType.ENUM_LIST_PACKED : FieldType.ENUM_LIST;
case FIXED32:
if (!fd.isRepeated()) {
return FieldType.FIXED32;
}
return fd.isPacked() ? FieldType.FIXED32_LIST_PACKED : FieldType.FIXED32_LIST;
case FIXED64:
if (!fd.isRepeated()) {
return FieldType.FIXED64;
}
return fd.isPacked() ? FieldType.FIXED64_LIST_PACKED : FieldType.FIXED64_LIST;
case FLOAT:
if (!fd.isRepeated()) {
return FieldType.FLOAT;
}
return fd.isPacked() ? FieldType.FLOAT_LIST_PACKED : FieldType.FLOAT_LIST;
case GROUP:
return fd.isRepeated() ? FieldType.GROUP_LIST : FieldType.GROUP;
case INT32:
if (!fd.isRepeated()) {
return FieldType.INT32;
}
return fd.isPacked() ? FieldType.INT32_LIST_PACKED : FieldType.INT32_LIST;
case INT64:
if (!fd.isRepeated()) {
return FieldType.INT64;
}
return fd.isPacked() ? FieldType.INT64_LIST_PACKED : FieldType.INT64_LIST;
case MESSAGE:
if (fd.isMapField()) {
return FieldType.MAP;
}
return fd.isRepeated() ? FieldType.MESSAGE_LIST : FieldType.MESSAGE;
case SFIXED32:
if (!fd.isRepeated()) {
return FieldType.SFIXED32;
}
return fd.isPacked() ? FieldType.SFIXED32_LIST_PACKED : FieldType.SFIXED32_LIST;
case SFIXED64:
if (!fd.isRepeated()) {
return FieldType.SFIXED64;
}
return fd.isPacked() ? FieldType.SFIXED64_LIST_PACKED : FieldType.SFIXED64_LIST;
case SINT32:
if (!fd.isRepeated()) {
return FieldType.SINT32;
}
return fd.isPacked() ? FieldType.SINT32_LIST_PACKED : FieldType.SINT32_LIST;
case SINT64:
if (!fd.isRepeated()) {
return FieldType.SINT64;
}
return fd.isPacked() ? FieldType.SINT64_LIST_PACKED : FieldType.SINT64_LIST;
case STRING:
return fd.isRepeated() ? FieldType.STRING_LIST : FieldType.STRING;
case UINT32:
if (!fd.isRepeated()) {
return FieldType.UINT32;
}
return fd.isPacked() ? FieldType.UINT32_LIST_PACKED : FieldType.UINT32_LIST;
case UINT64:
if (!fd.isRepeated()) {
return FieldType.UINT64;
}
return fd.isPacked() ? FieldType.UINT64_LIST_PACKED : FieldType.UINT64_LIST;
default:
throw new IllegalArgumentException("Unsupported field type: " + fd.getType());
}
}
private static Field bitField(Class<?> messageType, int index) {
return field(messageType, "bitField" + index + "_");
}
private static Field field(Class<?> messageType, FieldDescriptor fd) {
return field(messageType, getFieldName(fd));
}
private static Field cachedSizeField(Class<?> messageType, FieldDescriptor fd) {
return field(messageType, getCachedSizeFieldName(fd));
}
private static Field field(Class<?> messageType, String fieldName) {
try {
return messageType.getDeclaredField(fieldName);
} catch (Exception e) {
throw new IllegalArgumentException(
"Unable to find field " + fieldName + " in message class " + messageType.getName());
}
}
static String getFieldName(FieldDescriptor fd) {
String name = (fd.getType() == FieldDescriptor.Type.GROUP)
? fd.getMessageType().getName()
: fd.getName();
String suffix = specialFieldNames.contains(name) ? "__" : "_";
return snakeCaseToCamelCase(name) + suffix;
}
private static String getCachedSizeFieldName(FieldDescriptor fd) {
return snakeCaseToCamelCase(fd.getName()) + "MemoizedSerializedSize";
}
/**
* This method must match exactly with the corresponding function in protocol compiler. See:
* https://github.com/google/protobuf/blob/v3.0.0/src/google/protobuf/compiler/java/java_helpers.cc#L153
*/
private static String snakeCaseToCamelCase(String snakeCase) {
StringBuilder sb = new StringBuilder(snakeCase.length() + 1);
boolean capNext = false;
for (int ctr = 0; ctr < snakeCase.length(); ctr++) {
char next = snakeCase.charAt(ctr);
if (next == '_') {
capNext = true;
} else if (Character.isDigit(next)) {
sb.append(next);
capNext = true;
} else if (capNext) {
sb.append(Character.toUpperCase(next));
capNext = false;
} else if (ctr == 0) {
sb.append(Character.toLowerCase(next));
} else {
sb.append(next);
}
}
return sb.toString();
}
/**
* Inspects the message to identify the stored type for a message field that is part of a oneof.
*/
private static Class<?> getOneofStoredTypeForMessage(Class<?> messageType, FieldDescriptor fd) {
try {
String name = fd.getType() == Type.GROUP ? fd.getMessageType().getName() : fd.getName();
Method getter = messageType.getDeclaredMethod(getterForField(name));
return getter.getReturnType();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/** Inspects the message to identify the message type of a repeated message field. */
private static Class<?> getTypeForRepeatedMessageField(Class<?> messageType, FieldDescriptor fd) {
try {
String name = fd.getType() == Type.GROUP ? fd.getMessageType().getName() : fd.getName();
Method getter = messageType.getDeclaredMethod(getterForField(name), int.class);
return getter.getReturnType();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/** Constructs the name of the get method for the given field in the proto. */
private static String getterForField(String snakeCase) {
String camelCase = snakeCaseToCamelCase(snakeCase);
StringBuilder builder = new StringBuilder("get");
// Capitalize the first character in the field name.
builder.append(Character.toUpperCase(camelCase.charAt(0)));
builder.append(camelCase.substring(1, camelCase.length()));
return builder.toString();
}
private static final class OneofState {
private OneofInfo[] oneofs = new OneofInfo[2];
OneofInfo getOneof(Class<?> messageType, OneofDescriptor desc) {
int index = desc.getIndex();
if (index >= oneofs.length) {
// Grow the array.
oneofs = Arrays.copyOf(oneofs, index * 2);
}
OneofInfo info = oneofs[index];
if (info == null) {
info = newInfo(messageType, desc);
oneofs[index] = info;
}
return info;
}
private static OneofInfo newInfo(Class<?> messageType, OneofDescriptor desc) {
String camelCase = snakeCaseToCamelCase(desc.getName());
String valueFieldName = camelCase + "_";
String caseFieldName = camelCase + "Case_";
return new OneofInfo(
desc.getIndex(), field(messageType, caseFieldName), field(messageType, valueFieldName));
}
}
}

View File

@ -110,12 +110,23 @@ public class ExtensionRegistryLite {
return ExtensionRegistryFactory.create();
}
private static volatile ExtensionRegistryLite emptyRegistry;
/**
* Get the unmodifiable singleton empty instance of either ExtensionRegistryLite or {@code
* ExtensionRegistry} (if the full (non-Lite) proto libraries are available).
*/
public static ExtensionRegistryLite getEmptyRegistry() {
return ExtensionRegistryFactory.createEmpty();
ExtensionRegistryLite result = emptyRegistry;
if (result == null) {
synchronized (ExtensionRegistryLite.class) {
result = emptyRegistry;
if (result == null) {
result = emptyRegistry = ExtensionRegistryFactory.createEmpty();
}
}
}
return result;
}

View File

@ -0,0 +1,98 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.io.IOException;
import java.util.Map;
abstract class ExtensionSchema<T extends FieldSet.FieldDescriptorLite<T>> {
/** Returns true for messages that support extensions. */
abstract boolean hasExtensions(MessageLite prototype);
/** Returns the extension {@link FieldSet} for the message instance. */
abstract FieldSet<T> getExtensions(Object message);
/** Replaces the extension {@link FieldSet} for the message instance. */
abstract void setExtensions(Object message, FieldSet<T> extensions);
/** Returns the extension {@link FieldSet} and ensures it's mutable. */
abstract FieldSet<T> getMutableExtensions(Object message);
/** Marks the extension {@link FieldSet} as immutable. */
abstract void makeImmutable(Object message);
/**
* Parses an extension. Returns the passed-in unknownFields parameter if no unknown enum value is
* found or a modified unknownFields (a new instance if the passed-in unknownFields is null)
* containing unknown enum values found while parsing.
*
* @param <UT> The type used to store unknown fields. It's either UnknownFieldSet in full runtime
* or UnknownFieldSetLite in lite runtime.
*/
abstract <UT, UB> UB parseExtension(
Reader reader,
Object extension,
ExtensionRegistryLite extensionRegistry,
FieldSet<T> extensions,
UB unknownFields,
UnknownFieldSchema<UT, UB> unknownFieldSchema)
throws IOException;
/** Gets the field number of an extension entry. */
abstract int extensionNumber(Map.Entry<?, ?> extension);
/** Serializes one extension entry. */
abstract void serializeExtension(Writer writer, Map.Entry<?, ?> extension) throws IOException;
/** Finds an extension by field number. */
abstract Object findExtensionByNumber(
ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number);
/** Parses a length-prefixed MessageSet item from the reader. */
abstract void parseLengthPrefixedMessageSetItem(
Reader reader,
Object extension,
ExtensionRegistryLite extensionRegistry,
FieldSet<T> extensions)
throws IOException;
/**
* Parses the entire content of a {@link ByteString} as one MessageSet item. Unlike {@link
* #parseLengthPrefixedMessageSetItem}, there isn't a length-prefix.
*/
abstract void parseMessageSetItem(
ByteString data,
Object extension,
ExtensionRegistryLite extensionRegistry,
FieldSet<T> extensions)
throws IOException;
}

View File

@ -0,0 +1,547 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.Descriptors.EnumValueDescriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@SuppressWarnings("unchecked")
final class ExtensionSchemaFull extends ExtensionSchema<FieldDescriptor> {
private static final long EXTENSION_FIELD_OFFSET = getExtensionsFieldOffset();
private static <T> long getExtensionsFieldOffset() {
try {
Field field = GeneratedMessageV3.ExtendableMessage.class.getDeclaredField("extensions");
return UnsafeUtil.objectFieldOffset(field);
} catch (Throwable e) {
throw new IllegalStateException("Unable to lookup extension field offset");
}
}
@Override
boolean hasExtensions(MessageLite prototype) {
return prototype instanceof GeneratedMessageV3.ExtendableMessage;
}
@Override
public FieldSet<FieldDescriptor> getExtensions(Object message) {
return (FieldSet<FieldDescriptor>) UnsafeUtil.getObject(message, EXTENSION_FIELD_OFFSET);
}
@Override
void setExtensions(Object message, FieldSet<FieldDescriptor> extensions) {
UnsafeUtil.putObject(message, EXTENSION_FIELD_OFFSET, extensions);
}
@Override
FieldSet<FieldDescriptor> getMutableExtensions(Object message) {
FieldSet<FieldDescriptor> extensions = getExtensions(message);
if (extensions.isImmutable()) {
extensions = extensions.clone();
setExtensions(message, extensions);
}
return extensions;
}
@Override
void makeImmutable(Object message) {
getExtensions(message).makeImmutable();
}
@Override
<UT, UB> UB parseExtension(
Reader reader,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
FieldSet<FieldDescriptor> extensions,
UB unknownFields,
UnknownFieldSchema<UT, UB> unknownFieldSchema)
throws IOException {
ExtensionRegistry.ExtensionInfo extension = (ExtensionRegistry.ExtensionInfo) extensionObject;
int fieldNumber = extension.descriptor.getNumber();
if (extension.descriptor.isRepeated() && extension.descriptor.isPacked()) {
Object value = null;
switch (extension.descriptor.getLiteType()) {
case DOUBLE:
{
List<Double> list = new ArrayList<Double>();
reader.readDoubleList(list);
value = list;
break;
}
case FLOAT:
{
List<Float> list = new ArrayList<Float>();
reader.readFloatList(list);
value = list;
break;
}
case INT64:
{
List<Long> list = new ArrayList<Long>();
reader.readInt64List(list);
value = list;
break;
}
case UINT64:
{
List<Long> list = new ArrayList<Long>();
reader.readUInt64List(list);
value = list;
break;
}
case INT32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readInt32List(list);
value = list;
break;
}
case FIXED64:
{
List<Long> list = new ArrayList<Long>();
reader.readFixed64List(list);
value = list;
break;
}
case FIXED32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readFixed32List(list);
value = list;
break;
}
case BOOL:
{
List<Boolean> list = new ArrayList<Boolean>();
reader.readBoolList(list);
value = list;
break;
}
case UINT32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readUInt32List(list);
value = list;
break;
}
case SFIXED32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readSFixed32List(list);
value = list;
break;
}
case SFIXED64:
{
List<Long> list = new ArrayList<Long>();
reader.readSFixed64List(list);
value = list;
break;
}
case SINT32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readSInt32List(list);
value = list;
break;
}
case SINT64:
{
List<Long> list = new ArrayList<Long>();
reader.readSInt64List(list);
value = list;
break;
}
case ENUM:
{
List<Integer> list = new ArrayList<Integer>();
reader.readEnumList(list);
List<EnumValueDescriptor> enumList = new ArrayList<EnumValueDescriptor>();
for (int number : list) {
EnumValueDescriptor enumDescriptor =
extension.descriptor.getEnumType().findValueByNumber(number);
if (enumDescriptor != null) {
enumList.add(enumDescriptor);
} else {
unknownFields =
SchemaUtil.storeUnknownEnum(
fieldNumber, number, unknownFields, unknownFieldSchema);
}
}
value = enumList;
break;
}
default:
throw new IllegalStateException(
"Type cannot be packed: " + extension.descriptor.getLiteType());
}
extensions.setField(extension.descriptor, value);
} else {
Object value = null;
// Enum is a special case because unknown enum values will be put into UnknownFieldSetLite.
if (extension.descriptor.getLiteType() == WireFormat.FieldType.ENUM) {
int number = reader.readInt32();
Object enumValue = extension.descriptor.getEnumType().findValueByNumber(number);
if (enumValue == null) {
return SchemaUtil.storeUnknownEnum(
fieldNumber, number, unknownFields, unknownFieldSchema);
}
value = enumValue;
} else {
switch (extension.descriptor.getLiteType()) {
case DOUBLE:
value = reader.readDouble();
break;
case FLOAT:
value = reader.readFloat();
break;
case INT64:
value = reader.readInt64();
break;
case UINT64:
value = reader.readUInt64();
break;
case INT32:
value = reader.readInt32();
break;
case FIXED64:
value = reader.readFixed64();
break;
case FIXED32:
value = reader.readFixed32();
break;
case BOOL:
value = reader.readBool();
break;
case BYTES:
value = reader.readBytes();
break;
case UINT32:
value = reader.readUInt32();
break;
case SFIXED32:
value = reader.readSFixed32();
break;
case SFIXED64:
value = reader.readSFixed64();
break;
case SINT32:
value = reader.readSInt32();
break;
case SINT64:
value = reader.readSInt64();
break;
case STRING:
value = reader.readString();
break;
case GROUP:
value = reader.readGroup(extension.defaultInstance.getClass(), extensionRegistry);
break;
case MESSAGE:
value = reader.readMessage(extension.defaultInstance.getClass(), extensionRegistry);
break;
case ENUM:
throw new IllegalStateException("Shouldn't reach here.");
}
}
if (extension.descriptor.isRepeated()) {
extensions.addRepeatedField(extension.descriptor, value);
} else {
switch (extension.descriptor.getLiteType()) {
case MESSAGE:
case GROUP:
Object oldValue = extensions.getField(extension.descriptor);
if (oldValue != null) {
value = Internal.mergeMessage(oldValue, value);
}
break;
default:
break;
}
extensions.setField(extension.descriptor, value);
}
}
return unknownFields;
}
@Override
int extensionNumber(Map.Entry<?, ?> extension) {
FieldDescriptor descriptor = (FieldDescriptor) extension.getKey();
return descriptor.getNumber();
}
@Override
void serializeExtension(Writer writer, Map.Entry<?, ?> extension) throws IOException {
FieldDescriptor descriptor = (FieldDescriptor) extension.getKey();
if (descriptor.isRepeated()) {
switch (descriptor.getLiteType()) {
case DOUBLE:
SchemaUtil.writeDoubleList(
descriptor.getNumber(),
(List<Double>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FLOAT:
SchemaUtil.writeFloatList(
descriptor.getNumber(),
(List<Float>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case INT64:
SchemaUtil.writeInt64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case UINT64:
SchemaUtil.writeUInt64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case INT32:
SchemaUtil.writeInt32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FIXED64:
SchemaUtil.writeFixed64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FIXED32:
SchemaUtil.writeFixed32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case BOOL:
SchemaUtil.writeBoolList(
descriptor.getNumber(),
(List<Boolean>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case BYTES:
SchemaUtil.writeBytesList(
descriptor.getNumber(), (List<ByteString>) extension.getValue(), writer);
break;
case UINT32:
SchemaUtil.writeUInt32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SFIXED32:
SchemaUtil.writeSFixed32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SFIXED64:
SchemaUtil.writeSFixed64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SINT32:
SchemaUtil.writeSInt32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SINT64:
SchemaUtil.writeSInt64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case ENUM:
{
List<EnumValueDescriptor> enumList = (List<EnumValueDescriptor>) extension.getValue();
List<Integer> list = new ArrayList<Integer>();
for (EnumValueDescriptor d : enumList) {
list.add(d.getNumber());
}
SchemaUtil.writeInt32List(descriptor.getNumber(), list, writer, descriptor.isPacked());
break;
}
case STRING:
SchemaUtil.writeStringList(
descriptor.getNumber(), (List<String>) extension.getValue(), writer);
break;
case GROUP:
SchemaUtil.writeGroupList(descriptor.getNumber(), (List<?>) extension.getValue(), writer);
break;
case MESSAGE:
SchemaUtil.writeMessageList(
descriptor.getNumber(), (List<?>) extension.getValue(), writer);
break;
}
} else {
switch (descriptor.getLiteType()) {
case DOUBLE:
writer.writeDouble(descriptor.getNumber(), (Double) extension.getValue());
break;
case FLOAT:
writer.writeFloat(descriptor.getNumber(), (Float) extension.getValue());
break;
case INT64:
writer.writeInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case UINT64:
writer.writeUInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case INT32:
writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case FIXED64:
writer.writeFixed64(descriptor.getNumber(), (Long) extension.getValue());
break;
case FIXED32:
writer.writeFixed32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case BOOL:
writer.writeBool(descriptor.getNumber(), (Boolean) extension.getValue());
break;
case BYTES:
writer.writeBytes(descriptor.getNumber(), (ByteString) extension.getValue());
break;
case UINT32:
writer.writeUInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SFIXED32:
writer.writeSFixed32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SFIXED64:
writer.writeSFixed64(descriptor.getNumber(), (Long) extension.getValue());
break;
case SINT32:
writer.writeSInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SINT64:
writer.writeSInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case ENUM:
writer.writeInt32(
descriptor.getNumber(), ((EnumValueDescriptor) extension.getValue()).getNumber());
break;
case STRING:
writer.writeString(descriptor.getNumber(), (String) extension.getValue());
break;
case GROUP:
writer.writeGroup(descriptor.getNumber(), extension.getValue());
break;
case MESSAGE:
writer.writeMessage(descriptor.getNumber(), extension.getValue());
break;
}
}
}
@Override
Object findExtensionByNumber(
ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number) {
return ((ExtensionRegistry) extensionRegistry)
.findExtensionByNumber(((Message) defaultInstance).getDescriptorForType(), number);
}
@Override
void parseLengthPrefixedMessageSetItem(
Reader reader,
Object extension,
ExtensionRegistryLite extensionRegistry,
FieldSet<FieldDescriptor> extensions)
throws IOException {
ExtensionRegistry.ExtensionInfo extensionInfo = (ExtensionRegistry.ExtensionInfo) extension;
if (ExtensionRegistryLite.isEagerlyParseMessageSets()) {
Object value =
reader.readMessage(extensionInfo.defaultInstance.getClass(), extensionRegistry);
extensions.setField(extensionInfo.descriptor, value);
} else {
extensions.setField(
extensionInfo.descriptor,
new LazyField(extensionInfo.defaultInstance, extensionRegistry, reader.readBytes()));
}
}
@Override
void parseMessageSetItem(
ByteString data,
Object extension,
ExtensionRegistryLite extensionRegistry,
FieldSet<FieldDescriptor> extensions)
throws IOException {
ExtensionRegistry.ExtensionInfo extensionInfo = (ExtensionRegistry.ExtensionInfo) extension;
Object value = extensionInfo.defaultInstance.newBuilderForType().buildPartial();
if (ExtensionRegistryLite.isEagerlyParseMessageSets()) {
Reader reader = BinaryReader.newInstance(ByteBuffer.wrap(data.toByteArray()), true);
Protobuf.getInstance().mergeFrom(value, reader, extensionRegistry);
extensions.setField(extensionInfo.descriptor, value);
if (reader.getFieldNumber() != Reader.READ_DONE) {
throw InvalidProtocolBufferException.invalidEndTag();
}
} else {
extensions.setField(
extensionInfo.descriptor,
new LazyField(extensionInfo.defaultInstance, extensionRegistry, data));
}
}
}

View File

@ -0,0 +1,541 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.GeneratedMessageLite.ExtensionDescriptor;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@SuppressWarnings("unchecked")
final class ExtensionSchemaLite extends ExtensionSchema<ExtensionDescriptor> {
@Override
boolean hasExtensions(MessageLite prototype) {
return prototype instanceof GeneratedMessageLite.ExtendableMessage;
}
@Override
FieldSet<ExtensionDescriptor> getExtensions(Object message) {
return ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).extensions;
}
@Override
void setExtensions(Object message, FieldSet<ExtensionDescriptor> extensions) {
((GeneratedMessageLite.ExtendableMessage<?, ?>) message).extensions = extensions;
}
@Override
FieldSet<ExtensionDescriptor> getMutableExtensions(Object message) {
return ((GeneratedMessageLite.ExtendableMessage<?, ?>) message).ensureExtensionsAreMutable();
}
@Override
void makeImmutable(Object message) {
getExtensions(message).makeImmutable();
}
@Override
<UT, UB> UB parseExtension(
Reader reader,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
FieldSet<ExtensionDescriptor> extensions,
UB unknownFields,
UnknownFieldSchema<UT, UB> unknownFieldSchema)
throws IOException {
GeneratedMessageLite.GeneratedExtension<?, ?> extension =
(GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
int fieldNumber = extension.getNumber();
if (extension.descriptor.isRepeated() && extension.descriptor.isPacked()) {
Object value = null;
switch (extension.getLiteType()) {
case DOUBLE:
{
List<Double> list = new ArrayList<Double>();
reader.readDoubleList(list);
value = list;
break;
}
case FLOAT:
{
List<Float> list = new ArrayList<Float>();
reader.readFloatList(list);
value = list;
break;
}
case INT64:
{
List<Long> list = new ArrayList<Long>();
reader.readInt64List(list);
value = list;
break;
}
case UINT64:
{
List<Long> list = new ArrayList<Long>();
reader.readUInt64List(list);
value = list;
break;
}
case INT32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readInt32List(list);
value = list;
break;
}
case FIXED64:
{
List<Long> list = new ArrayList<Long>();
reader.readFixed64List(list);
value = list;
break;
}
case FIXED32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readFixed32List(list);
value = list;
break;
}
case BOOL:
{
List<Boolean> list = new ArrayList<Boolean>();
reader.readBoolList(list);
value = list;
break;
}
case UINT32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readUInt32List(list);
value = list;
break;
}
case SFIXED32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readSFixed32List(list);
value = list;
break;
}
case SFIXED64:
{
List<Long> list = new ArrayList<Long>();
reader.readSFixed64List(list);
value = list;
break;
}
case SINT32:
{
List<Integer> list = new ArrayList<Integer>();
reader.readSInt32List(list);
value = list;
break;
}
case SINT64:
{
List<Long> list = new ArrayList<Long>();
reader.readSInt64List(list);
value = list;
break;
}
case ENUM:
{
List<Integer> list = new ArrayList<Integer>();
reader.readEnumList(list);
unknownFields =
SchemaUtil.filterUnknownEnumList(
fieldNumber,
list,
extension.descriptor.getEnumType(),
unknownFields,
unknownFieldSchema);
value = list;
break;
}
default:
throw new IllegalStateException(
"Type cannot be packed: " + extension.descriptor.getLiteType());
}
extensions.setField(extension.descriptor, value);
} else {
Object value = null;
// Enum is a special case becasue unknown enum values will be put into UnknownFieldSetLite.
if (extension.getLiteType() == WireFormat.FieldType.ENUM) {
int number = reader.readInt32();
Object enumValue = extension.descriptor.getEnumType().findValueByNumber(number);
if (enumValue == null) {
return SchemaUtil.storeUnknownEnum(
fieldNumber, number, unknownFields, unknownFieldSchema);
}
// Note, we store the integer value instead of the actual enum object in FieldSet.
// This is also different from full-runtime where we store EnumValueDescriptor.
value = number;
} else {
switch (extension.getLiteType()) {
case DOUBLE:
value = reader.readDouble();
break;
case FLOAT:
value = reader.readFloat();
break;
case INT64:
value = reader.readInt64();
break;
case UINT64:
value = reader.readUInt64();
break;
case INT32:
value = reader.readInt32();
break;
case FIXED64:
value = reader.readFixed64();
break;
case FIXED32:
value = reader.readFixed32();
break;
case BOOL:
value = reader.readBool();
break;
case BYTES:
value = reader.readBytes();
break;
case UINT32:
value = reader.readUInt32();
break;
case SFIXED32:
value = reader.readSFixed32();
break;
case SFIXED64:
value = reader.readSFixed64();
break;
case SINT32:
value = reader.readSInt32();
break;
case SINT64:
value = reader.readSInt64();
break;
case STRING:
value = reader.readString();
break;
case GROUP:
value =
reader.readGroup(
extension.getMessageDefaultInstance().getClass(), extensionRegistry);
break;
case MESSAGE:
value =
reader.readMessage(
extension.getMessageDefaultInstance().getClass(), extensionRegistry);
break;
case ENUM:
throw new IllegalStateException("Shouldn't reach here.");
}
}
if (extension.isRepeated()) {
extensions.addRepeatedField(extension.descriptor, value);
} else {
switch (extension.getLiteType()) {
case MESSAGE:
case GROUP:
Object oldValue = extensions.getField(extension.descriptor);
if (oldValue != null) {
value = Internal.mergeMessage(oldValue, value);
}
break;
default:
break;
}
extensions.setField(extension.descriptor, value);
}
}
return unknownFields;
}
@Override
int extensionNumber(Map.Entry<?, ?> extension) {
GeneratedMessageLite.ExtensionDescriptor descriptor =
(GeneratedMessageLite.ExtensionDescriptor) extension.getKey();
return descriptor.getNumber();
}
@Override
void serializeExtension(Writer writer, Map.Entry<?, ?> extension) throws IOException {
GeneratedMessageLite.ExtensionDescriptor descriptor =
(GeneratedMessageLite.ExtensionDescriptor) extension.getKey();
if (descriptor.isRepeated()) {
switch (descriptor.getLiteType()) {
case DOUBLE:
SchemaUtil.writeDoubleList(
descriptor.getNumber(),
(List<Double>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FLOAT:
SchemaUtil.writeFloatList(
descriptor.getNumber(),
(List<Float>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case INT64:
SchemaUtil.writeInt64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case UINT64:
SchemaUtil.writeUInt64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case INT32:
SchemaUtil.writeInt32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FIXED64:
SchemaUtil.writeFixed64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case FIXED32:
SchemaUtil.writeFixed32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case BOOL:
SchemaUtil.writeBoolList(
descriptor.getNumber(),
(List<Boolean>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case BYTES:
SchemaUtil.writeBytesList(
descriptor.getNumber(), (List<ByteString>) extension.getValue(), writer);
break;
case UINT32:
SchemaUtil.writeUInt32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SFIXED32:
SchemaUtil.writeSFixed32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SFIXED64:
SchemaUtil.writeSFixed64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SINT32:
SchemaUtil.writeSInt32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case SINT64:
SchemaUtil.writeSInt64List(
descriptor.getNumber(),
(List<Long>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case ENUM:
SchemaUtil.writeInt32List(
descriptor.getNumber(),
(List<Integer>) extension.getValue(),
writer,
descriptor.isPacked());
break;
case STRING:
SchemaUtil.writeStringList(
descriptor.getNumber(), (List<String>) extension.getValue(), writer);
break;
case GROUP:
{
List<?> data = (List<?>) extension.getValue();
if (data != null && !data.isEmpty()) {
SchemaUtil.writeGroupList(
descriptor.getNumber(),
(List<?>) extension.getValue(),
writer,
Protobuf.getInstance().schemaFor(data.get(0).getClass()));
}
}
break;
case MESSAGE:
{
List<?> data = (List<?>) extension.getValue();
if (data != null && !data.isEmpty()) {
SchemaUtil.writeMessageList(
descriptor.getNumber(),
(List<?>) extension.getValue(),
writer,
Protobuf.getInstance().schemaFor(data.get(0).getClass()));
}
}
break;
}
} else {
switch (descriptor.getLiteType()) {
case DOUBLE:
writer.writeDouble(descriptor.getNumber(), (Double) extension.getValue());
break;
case FLOAT:
writer.writeFloat(descriptor.getNumber(), (Float) extension.getValue());
break;
case INT64:
writer.writeInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case UINT64:
writer.writeUInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case INT32:
writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case FIXED64:
writer.writeFixed64(descriptor.getNumber(), (Long) extension.getValue());
break;
case FIXED32:
writer.writeFixed32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case BOOL:
writer.writeBool(descriptor.getNumber(), (Boolean) extension.getValue());
break;
case BYTES:
writer.writeBytes(descriptor.getNumber(), (ByteString) extension.getValue());
break;
case UINT32:
writer.writeUInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SFIXED32:
writer.writeSFixed32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SFIXED64:
writer.writeSFixed64(descriptor.getNumber(), (Long) extension.getValue());
break;
case SINT32:
writer.writeSInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case SINT64:
writer.writeSInt64(descriptor.getNumber(), (Long) extension.getValue());
break;
case ENUM:
writer.writeInt32(descriptor.getNumber(), (Integer) extension.getValue());
break;
case STRING:
writer.writeString(descriptor.getNumber(), (String) extension.getValue());
break;
case GROUP:
writer.writeGroup(
descriptor.getNumber(),
extension.getValue(),
Protobuf.getInstance().schemaFor(extension.getValue().getClass()));
break;
case MESSAGE:
writer.writeMessage(
descriptor.getNumber(),
extension.getValue(),
Protobuf.getInstance().schemaFor(extension.getValue().getClass()));
break;
}
}
}
@Override
Object findExtensionByNumber(
ExtensionRegistryLite extensionRegistry, MessageLite defaultInstance, int number) {
return extensionRegistry.findLiteExtensionByNumber(defaultInstance, number);
}
@Override
void parseLengthPrefixedMessageSetItem(
Reader reader,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
FieldSet<ExtensionDescriptor> extensions)
throws IOException {
GeneratedMessageLite.GeneratedExtension<?, ?> extension =
(GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
Object value =
reader.readMessage(extension.getMessageDefaultInstance().getClass(), extensionRegistry);
extensions.setField(extension.descriptor, value);
}
@Override
void parseMessageSetItem(
ByteString data,
Object extensionObject,
ExtensionRegistryLite extensionRegistry,
FieldSet<ExtensionDescriptor> extensions)
throws IOException {
GeneratedMessageLite.GeneratedExtension<?, ?> extension =
(GeneratedMessageLite.GeneratedExtension<?, ?>) extensionObject;
Object value = extension.getMessageDefaultInstance().newBuilderForType().buildPartial();
Reader reader = BinaryReader.newInstance(ByteBuffer.wrap(data.toByteArray()), true);
Protobuf.getInstance().mergeFrom(value, reader, extensionRegistry);
extensions.setField(extension.descriptor, value);
if (reader.getFieldNumber() != Reader.READ_DONE) {
throw InvalidProtocolBufferException.invalidEndTag();
}
}
}

View File

@ -0,0 +1,56 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
final class ExtensionSchemas {
private static final ExtensionSchema<?> LITE_SCHEMA = new ExtensionSchemaLite();
private static final ExtensionSchema<?> FULL_SCHEMA = loadSchemaForFullRuntime();
private static ExtensionSchema<?> loadSchemaForFullRuntime() {
try {
Class<?> clazz = Class.forName("com.google.protobuf.ExtensionSchemaFull");
return (ExtensionSchema) clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
return null;
}
}
static ExtensionSchema<?> lite() {
return LITE_SCHEMA;
}
static ExtensionSchema<?> full() {
if (FULL_SCHEMA == null) {
throw new IllegalStateException("Protobuf runtime is not correctly loaded.");
}
return FULL_SCHEMA;
}
}

View File

@ -0,0 +1,577 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.Internal.checkNotNull;
import com.google.protobuf.Internal.EnumVerifier;
import java.lang.reflect.Field;
/** Information for a single field in a protobuf message class. */
@ExperimentalApi
final class FieldInfo implements Comparable<FieldInfo> {
private final Field field;
private final FieldType type;
private final Class<?> messageClass; // The message type for repeated message fields.
private final int fieldNumber;
private final Field presenceField;
private final int presenceMask;
private final boolean required;
private final boolean enforceUtf8;
private final OneofInfo oneof;
private final Field cachedSizeField;
/**
* The actual type stored in the oneof value for this field. Since the oneof value is an {@link
* Object}, primitives will store their boxed type. Only valid in conjunction with {@link #oneof}
* (both must be either null or non-null.
*/
private final Class<?> oneofStoredType;
// TODO(liujisi): make map default entry lazy?
private final Object mapDefaultEntry;
private final EnumVerifier enumVerifier;
/** Constructs a new descriptor for a field. */
public static FieldInfo forField(
Field field, int fieldNumber, FieldType fieldType, boolean enforceUtf8) {
checkFieldNumber(fieldNumber);
checkNotNull(field, "field");
checkNotNull(fieldType, "fieldType");
if (fieldType == FieldType.MESSAGE_LIST || fieldType == FieldType.GROUP_LIST) {
throw new IllegalStateException("Shouldn't be called for repeated message fields.");
}
return new FieldInfo(
field,
fieldNumber,
fieldType,
/* messageClass= */ null,
/* presenceField= */ null,
/* presenceMask= */ 0,
/* required= */ false,
enforceUtf8,
/* oneof= */ null,
/* oneofStoredType= */ null,
/* mapDefaultEntry= */ null,
/* enumVerifier= */ null,
/* cachedSizeField= */ null);
}
/** Constructs a new descriptor for a packed field. */
public static FieldInfo forPackedField(
Field field, int fieldNumber, FieldType fieldType, Field cachedSizeField) {
checkFieldNumber(fieldNumber);
checkNotNull(field, "field");
checkNotNull(fieldType, "fieldType");
if (fieldType == FieldType.MESSAGE_LIST || fieldType == FieldType.GROUP_LIST) {
throw new IllegalStateException("Shouldn't be called for repeated message fields.");
}
return new FieldInfo(
field,
fieldNumber,
fieldType,
/* messageClass= */ null,
/* presenceField= */ null,
/* presenceMask= */ 0,
/* required= */ false,
/* enforceUtf8= */ false,
/* oneof= */ null,
/* oneofStoredType= */ null,
/* mapDefaultEntry= */ null,
/* enumVerifier= */ null,
cachedSizeField);
}
/** Constructs a new descriptor for a repeated message field. */
public static FieldInfo forRepeatedMessageField(
Field field, int fieldNumber, FieldType fieldType, Class<?> messageClass) {
checkFieldNumber(fieldNumber);
checkNotNull(field, "field");
checkNotNull(fieldType, "fieldType");
checkNotNull(messageClass, "messageClass");
return new FieldInfo(
field,
fieldNumber,
fieldType,
messageClass,
/* presenceField= */ null,
/* presenceMask= */ 0,
/* required= */ false,
/* enforceUtf8= */ false,
/* oneof= */ null,
/* oneofStoredType= */ null,
/* mapDefaultEntry= */ null,
/* enumVerifier= */ null,
/* cachedSizeField= */ null);
}
public static FieldInfo forFieldWithEnumVerifier(
Field field, int fieldNumber, FieldType fieldType, EnumVerifier enumVerifier) {
checkFieldNumber(fieldNumber);
checkNotNull(field, "field");
return new FieldInfo(
field,
fieldNumber,
fieldType,
/* messageClass= */ null,
/* presenceField= */ null,
/* presenceMask= */ 0,
/* required= */ false,
/* enforceUtf8= */ false,
/* oneof= */ null,
/* oneofStoredType= */ null,
/* mapDefaultEntry= */ null,
enumVerifier,
/* cachedSizeField= */ null);
}
public static FieldInfo forPackedFieldWithEnumVerifier(
Field field,
int fieldNumber,
FieldType fieldType,
EnumVerifier enumVerifier,
Field cachedSizeField) {
checkFieldNumber(fieldNumber);
checkNotNull(field, "field");
return new FieldInfo(
field,
fieldNumber,
fieldType,
/* messageClass= */ null,
/* presenceField= */ null,
/* presenceMask= */ 0,
/* required= */ false,
/* enforceUtf8= */ false,
/* oneof= */ null,
/* oneofStoredType= */ null,
/* mapDefaultEntry= */ null,
enumVerifier,
cachedSizeField);
}
/** Constructor for a proto2 optional field. */
public static FieldInfo forProto2OptionalField(
Field field,
int fieldNumber,
FieldType fieldType,
Field presenceField,
int presenceMask,
boolean enforceUtf8,
EnumVerifier enumVerifier) {
checkFieldNumber(fieldNumber);
checkNotNull(field, "field");
checkNotNull(fieldType, "fieldType");
checkNotNull(presenceField, "presenceField");
if (presenceField != null && !isExactlyOneBitSet(presenceMask)) {
throw new IllegalArgumentException(
"presenceMask must have exactly one bit set: " + presenceMask);
}
return new FieldInfo(
field,
fieldNumber,
fieldType,
/* messageClass= */ null,
presenceField,
presenceMask,
/* required= */ false,
enforceUtf8,
/* oneof= */ null,
/* oneofStoredType= */ null,
/* mapDefaultEntry= */ null,
enumVerifier,
/* cachedSizeField= */ null);
}
/**
* Constructor for a field that is part of a oneof.
*
* @param fieldNumber the unique field number for this field within the message.
* @param fieldType the type of the field (must be non-null).
* @param oneof the oneof for which this field is associated (must be non-null).
* @param oneofStoredType the actual type stored in the oneof value for this field. Since the
* oneof value is an {@link Object}, primitives will store their boxed type. Must be non-null.
* @param enforceUtf8 Only used for string fields. If {@code true}, will enforce UTF-8 on a string
* field.
* @return the {@link FieldInfo} describing this field.
*/
public static FieldInfo forOneofMemberField(
int fieldNumber,
FieldType fieldType,
OneofInfo oneof,
Class<?> oneofStoredType,
boolean enforceUtf8,
EnumVerifier enumVerifier) {
checkFieldNumber(fieldNumber);
checkNotNull(fieldType, "fieldType");
checkNotNull(oneof, "oneof");
checkNotNull(oneofStoredType, "oneofStoredType");
if (!fieldType.isScalar()) {
throw new IllegalArgumentException(
"Oneof is only supported for scalar fields. Field "
+ fieldNumber
+ " is of type "
+ fieldType);
}
return new FieldInfo(
/* field= */ null,
fieldNumber,
fieldType,
/* messageClass= */ null,
/* presenceField= */ null,
/* presenceMask= */ 0,
/* required= */ false,
enforceUtf8,
oneof,
oneofStoredType,
/* mapDefaultEntry= */ null,
enumVerifier,
/* cachedSizeField= */ null);
}
private static void checkFieldNumber(int fieldNumber) {
if (fieldNumber <= 0) {
throw new IllegalArgumentException("fieldNumber must be positive: " + fieldNumber);
}
}
/** Constructor for a proto2 required field. */
public static FieldInfo forProto2RequiredField(
Field field,
int fieldNumber,
FieldType fieldType,
Field presenceField,
int presenceMask,
boolean enforceUtf8,
EnumVerifier enumVerifier) {
checkFieldNumber(fieldNumber);
checkNotNull(field, "field");
checkNotNull(fieldType, "fieldType");
checkNotNull(presenceField, "presenceField");
if (presenceField != null && !isExactlyOneBitSet(presenceMask)) {
throw new IllegalArgumentException(
"presenceMask must have exactly one bit set: " + presenceMask);
}
return new FieldInfo(
field,
fieldNumber,
fieldType,
/* messageClass= */ null,
presenceField,
presenceMask,
/* required= */ true,
enforceUtf8,
/* oneof= */ null,
/* oneofStoredType= */ null,
/* mapDefaultEntry= */ null,
/* enumVerifier= */ enumVerifier,
/* cachedSizeField= */ null);
}
public static FieldInfo forMapField(
Field field, int fieldNumber, Object mapDefaultEntry, EnumVerifier enumVerifier) {
checkNotNull(mapDefaultEntry, "mapDefaultEntry");
checkFieldNumber(fieldNumber);
checkNotNull(field, "field");
return new FieldInfo(
field,
fieldNumber,
FieldType.MAP,
/* messageClass= */ null,
/* presenceField= */ null,
/* presenceMask= */ 0,
/* required= */ false,
/* enforceUtf8= */ true,
/* oneof= */ null,
/* oneofStoredType= */ null,
mapDefaultEntry,
enumVerifier,
/* cachedSizeField= */ null);
}
private FieldInfo(
Field field,
int fieldNumber,
FieldType type,
Class<?> messageClass,
Field presenceField,
int presenceMask,
boolean required,
boolean enforceUtf8,
OneofInfo oneof,
Class<?> oneofStoredType,
Object mapDefaultEntry,
EnumVerifier enumVerifier,
Field cachedSizeField) {
this.field = field;
this.type = type;
this.messageClass = messageClass;
this.fieldNumber = fieldNumber;
this.presenceField = presenceField;
this.presenceMask = presenceMask;
this.required = required;
this.enforceUtf8 = enforceUtf8;
this.oneof = oneof;
this.oneofStoredType = oneofStoredType;
this.mapDefaultEntry = mapDefaultEntry;
this.enumVerifier = enumVerifier;
this.cachedSizeField = cachedSizeField;
}
/** Gets the field number for the field. */
public int getFieldNumber() {
return fieldNumber;
}
/** Gets the subject {@link Field} of this descriptor. */
public Field getField() {
return field;
}
/** Gets the type information for the field. */
public FieldType getType() {
return type;
}
/** Gets the oneof for which this field is a member, or {@code null} if not part of a oneof. */
public OneofInfo getOneof() {
return oneof;
}
/**
* Gets the actual type stored in the oneof value by this field. Since the oneof value is an
* {@link Object}, primitives will store their boxed type. For non-oneof fields, this will always
* be {@code null}.
*/
public Class<?> getOneofStoredType() {
return oneofStoredType;
}
/** Gets the {@code EnumVerifier} if the field is an enum field. */
public EnumVerifier getEnumVerifier() {
return enumVerifier;
}
@Override
public int compareTo(FieldInfo o) {
return fieldNumber - o.fieldNumber;
}
/**
* For repeated message fields, returns the message type of the field. For other fields, returns
* {@code null}.
*/
public Class<?> getListElementType() {
return messageClass;
}
/** Gets the presence bit field. Only valid for unary fields. For lists, returns {@code null}. */
public Field getPresenceField() {
return presenceField;
}
public Object getMapDefaultEntry() {
return mapDefaultEntry;
}
/**
* If {@link #getPresenceField()} is non-{@code null}, returns the mask used to identify the
* presence bit for this field in the message.
*/
public int getPresenceMask() {
return presenceMask;
}
/** Whether this is a required field. */
public boolean isRequired() {
return required;
}
/**
* Whether a UTF-8 should be enforced on string fields. Only applies to strings and string lists.
*/
public boolean isEnforceUtf8() {
return enforceUtf8;
}
public Field getCachedSizeField() {
return cachedSizeField;
}
/**
* For singular or repeated message fields, returns the message type. For other fields, returns
* {@code null}.
*/
public Class<?> getMessageFieldClass() {
switch (type) {
case MESSAGE:
case GROUP:
return field != null ? field.getType() : oneofStoredType;
case MESSAGE_LIST:
case GROUP_LIST:
return messageClass;
default:
return null;
}
}
public static Builder newBuilder() {
return new Builder();
}
/** A builder for {@link FieldInfo} instances. */
public static final class Builder {
private Field field;
private FieldType type;
private int fieldNumber;
private Field presenceField;
private int presenceMask;
private boolean required;
private boolean enforceUtf8;
private OneofInfo oneof;
private Class<?> oneofStoredType;
private Object mapDefaultEntry;
private EnumVerifier enumVerifier;
private Field cachedSizeField;
private Builder() {}
/**
* Specifies the actual field on the message represented by this field. This should not be
* called for oneof member fields.
*/
public Builder withField(Field field) {
if (oneof != null) {
throw new IllegalStateException("Cannot set field when building a oneof.");
}
this.field = field;
return this;
}
/** Specifies the type of this field. */
public Builder withType(FieldType type) {
this.type = type;
return this;
}
/** Specifies the unique field number for this field within the message. */
public Builder withFieldNumber(int fieldNumber) {
this.fieldNumber = fieldNumber;
return this;
}
/** Specifies proto2 presence information. This should not be called for oneof fields. */
public Builder withPresence(Field presenceField, int presenceMask) {
this.presenceField = checkNotNull(presenceField, "presenceField");
this.presenceMask = presenceMask;
return this;
}
/**
* Sets the information for building a oneof member field. This is incompatible with {@link
* #withField(Field)} and {@link #withPresence(Field, int)}.
*
* @param oneof the oneof for which this field is associated.
* @param oneofStoredType the actual type stored in the oneof value for this field. Since the
* oneof value is an {@link Object}, primitives will store their boxed type.
*/
public Builder withOneof(OneofInfo oneof, Class<?> oneofStoredType) {
if (field != null || presenceField != null) {
throw new IllegalStateException(
"Cannot set oneof when field or presenceField have been provided");
}
this.oneof = oneof;
this.oneofStoredType = oneofStoredType;
return this;
}
public Builder withRequired(boolean required) {
this.required = required;
return this;
}
public Builder withMapDefaultEntry(Object mapDefaultEntry) {
this.mapDefaultEntry = mapDefaultEntry;
return this;
}
public Builder withEnforceUtf8(boolean enforceUtf8) {
this.enforceUtf8 = enforceUtf8;
return this;
}
public Builder withEnumVerifier(EnumVerifier enumVerifier) {
this.enumVerifier = enumVerifier;
return this;
}
public Builder withCachedSizeField(Field cachedSizeField) {
this.cachedSizeField = cachedSizeField;
return this;
}
public FieldInfo build() {
if (oneof != null) {
return forOneofMemberField(
fieldNumber, type, oneof, oneofStoredType, enforceUtf8, enumVerifier);
}
if (mapDefaultEntry != null) {
return forMapField(field, fieldNumber, mapDefaultEntry, enumVerifier);
}
if (presenceField != null) {
if (required) {
return forProto2RequiredField(
field, fieldNumber, type, presenceField, presenceMask, enforceUtf8, enumVerifier);
} else {
return forProto2OptionalField(
field, fieldNumber, type, presenceField, presenceMask, enforceUtf8, enumVerifier);
}
}
if (enumVerifier != null) {
if (cachedSizeField == null) {
return forFieldWithEnumVerifier(field, fieldNumber, type, enumVerifier);
} else {
return forPackedFieldWithEnumVerifier(
field, fieldNumber, type, enumVerifier, cachedSizeField);
}
} else {
if (cachedSizeField == null) {
return forField(field, fieldNumber, type, enforceUtf8);
} else {
return forPackedField(field, fieldNumber, type, cachedSizeField);
}
}
}
}
private static boolean isExactlyOneBitSet(int value) {
return value != 0 && (value & (value - 1)) == 0;
}
}

View File

@ -218,6 +218,17 @@ final class FieldSet<
return fields.entrySet().iterator();
}
/**
* Get an iterator over the fields in the map in descending (i.e. reverse) order. This iterator
* should not be leaked out of the protobuf library as it is not protected from mutation when
* fields is not immutable.
*/
Iterator<Map.Entry<FieldDescriptorType, Object>> descendingIterator() {
if (hasLazyField) {
return new LazyIterator<FieldDescriptorType>(fields.descendingEntrySet().iterator());
}
return fields.descendingEntrySet().iterator();
}
/** Useful for implementing {@link Message#hasField(Descriptors.FieldDescriptor)}. */
public boolean hasField(final FieldDescriptorType descriptor) {

View File

@ -0,0 +1,346 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;
/** Enumeration identifying all relevant type information for a protobuf field. */
@ExperimentalApi
public enum FieldType {
DOUBLE(0, Collection.SCALAR, JavaType.DOUBLE),
FLOAT(1, Collection.SCALAR, JavaType.FLOAT),
INT64(2, Collection.SCALAR, JavaType.LONG),
UINT64(3, Collection.SCALAR, JavaType.LONG),
INT32(4, Collection.SCALAR, JavaType.INT),
FIXED64(5, Collection.SCALAR, JavaType.LONG),
FIXED32(6, Collection.SCALAR, JavaType.INT),
BOOL(7, Collection.SCALAR, JavaType.BOOLEAN),
STRING(8, Collection.SCALAR, JavaType.STRING),
MESSAGE(9, Collection.SCALAR, JavaType.MESSAGE),
BYTES(10, Collection.SCALAR, JavaType.BYTE_STRING),
UINT32(11, Collection.SCALAR, JavaType.INT),
ENUM(12, Collection.SCALAR, JavaType.ENUM),
SFIXED32(13, Collection.SCALAR, JavaType.INT),
SFIXED64(14, Collection.SCALAR, JavaType.LONG),
SINT32(15, Collection.SCALAR, JavaType.INT),
SINT64(16, Collection.SCALAR, JavaType.LONG),
GROUP(17, Collection.SCALAR, JavaType.MESSAGE),
DOUBLE_LIST(18, Collection.VECTOR, JavaType.DOUBLE),
FLOAT_LIST(19, Collection.VECTOR, JavaType.FLOAT),
INT64_LIST(20, Collection.VECTOR, JavaType.LONG),
UINT64_LIST(21, Collection.VECTOR, JavaType.LONG),
INT32_LIST(22, Collection.VECTOR, JavaType.INT),
FIXED64_LIST(23, Collection.VECTOR, JavaType.LONG),
FIXED32_LIST(24, Collection.VECTOR, JavaType.INT),
BOOL_LIST(25, Collection.VECTOR, JavaType.BOOLEAN),
STRING_LIST(26, Collection.VECTOR, JavaType.STRING),
MESSAGE_LIST(27, Collection.VECTOR, JavaType.MESSAGE),
BYTES_LIST(28, Collection.VECTOR, JavaType.BYTE_STRING),
UINT32_LIST(29, Collection.VECTOR, JavaType.INT),
ENUM_LIST(30, Collection.VECTOR, JavaType.ENUM),
SFIXED32_LIST(31, Collection.VECTOR, JavaType.INT),
SFIXED64_LIST(32, Collection.VECTOR, JavaType.LONG),
SINT32_LIST(33, Collection.VECTOR, JavaType.INT),
SINT64_LIST(34, Collection.VECTOR, JavaType.LONG),
DOUBLE_LIST_PACKED(35, Collection.PACKED_VECTOR, JavaType.DOUBLE),
FLOAT_LIST_PACKED(36, Collection.PACKED_VECTOR, JavaType.FLOAT),
INT64_LIST_PACKED(37, Collection.PACKED_VECTOR, JavaType.LONG),
UINT64_LIST_PACKED(38, Collection.PACKED_VECTOR, JavaType.LONG),
INT32_LIST_PACKED(39, Collection.PACKED_VECTOR, JavaType.INT),
FIXED64_LIST_PACKED(40, Collection.PACKED_VECTOR, JavaType.LONG),
FIXED32_LIST_PACKED(41, Collection.PACKED_VECTOR, JavaType.INT),
BOOL_LIST_PACKED(42, Collection.PACKED_VECTOR, JavaType.BOOLEAN),
UINT32_LIST_PACKED(43, Collection.PACKED_VECTOR, JavaType.INT),
ENUM_LIST_PACKED(44, Collection.PACKED_VECTOR, JavaType.ENUM),
SFIXED32_LIST_PACKED(45, Collection.PACKED_VECTOR, JavaType.INT),
SFIXED64_LIST_PACKED(46, Collection.PACKED_VECTOR, JavaType.LONG),
SINT32_LIST_PACKED(47, Collection.PACKED_VECTOR, JavaType.INT),
SINT64_LIST_PACKED(48, Collection.PACKED_VECTOR, JavaType.LONG),
GROUP_LIST(49, Collection.VECTOR, JavaType.MESSAGE),
MAP(50, Collection.MAP, JavaType.VOID);
private final JavaType javaType;
private final int id;
private final Collection collection;
private final Class<?> elementType;
private final boolean primitiveScalar;
FieldType(int id, Collection collection, JavaType javaType) {
this.id = id;
this.collection = collection;
this.javaType = javaType;
switch (collection) {
case MAP:
elementType = javaType.getBoxedType();
break;
case VECTOR:
elementType = javaType.getBoxedType();
break;
case SCALAR:
default:
elementType = null;
break;
}
boolean primitiveScalar = false;
if (collection == Collection.SCALAR) {
switch (javaType) {
case BYTE_STRING:
case MESSAGE:
case STRING:
break;
default:
primitiveScalar = true;
break;
}
}
this.primitiveScalar = primitiveScalar;
}
/** A reliable unique identifier for this type. */
public int id() {
return id;
}
/**
* Gets the {@link JavaType} for this field. For lists, this identifies the type of the elements
* contained within the list.
*/
public JavaType getJavaType() {
return javaType;
}
/** Indicates whether a list field should be represented on the wire in packed form. */
public boolean isPacked() {
return Collection.PACKED_VECTOR.equals(collection);
}
/**
* Indicates whether this field type represents a primitive scalar value. If this is {@code true},
* then {@link #isScalar()} will also be {@code true}.
*/
public boolean isPrimitiveScalar() {
return primitiveScalar;
}
/** Indicates whether this field type represents a scalar value. */
public boolean isScalar() {
return collection == Collection.SCALAR;
}
/** Indicates whether this field represents a list of values. */
public boolean isList() {
return collection.isList();
}
/** Indicates whether this field represents a map. */
public boolean isMap() {
return collection == Collection.MAP;
}
/** Indicates whether or not this {@link FieldType} can be applied to the given {@link Field}. */
public boolean isValidForField(Field field) {
if (Collection.VECTOR.equals(collection)) {
return isValidForList(field);
} else {
return javaType.getType().isAssignableFrom(field.getType());
}
}
private boolean isValidForList(Field field) {
Class<?> clazz = field.getType();
if (!javaType.getType().isAssignableFrom(clazz)) {
// The field isn't a List type.
return false;
}
Type[] types = EMPTY_TYPES;
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
types = ((ParameterizedType) field.getGenericType()).getActualTypeArguments();
}
Type listParameter = getListParameter(clazz, types);
if (!(listParameter instanceof Class)) {
// It's a wildcard, we should allow anything in the list.
return true;
}
return elementType.isAssignableFrom((Class<?>) listParameter);
}
/**
* Looks up the appropriate {@link FieldType} by it's identifier.
*
* @return the {@link FieldType} or {@code null} if not found.
*/
/* @Nullable */
public static FieldType forId(int id) {
if (id < 0 || id >= VALUES.length) {
return null;
}
return VALUES[id];
}
private static final FieldType[] VALUES;
private static final Type[] EMPTY_TYPES = new Type[0];
static {
FieldType[] values = values();
VALUES = new FieldType[values.length];
for (FieldType type : values) {
VALUES[type.id] = type;
}
}
/**
* Given a class, finds a generic super class or interface that extends {@link List}.
*
* @return the generic super class/interface, or {@code null} if not found.
*/
/* @Nullable */
private static Type getGenericSuperList(Class<?> clazz) {
// First look at interfaces.
Type[] genericInterfaces = clazz.getGenericInterfaces();
for (Type genericInterface : genericInterfaces) {
if (genericInterface instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
Class<?> rawType = (Class<?>) parameterizedType.getRawType();
if (List.class.isAssignableFrom(rawType)) {
return genericInterface;
}
}
}
// Try the subclass
Type type = clazz.getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Class<?> rawType = (Class<?>) parameterizedType.getRawType();
if (List.class.isAssignableFrom(rawType)) {
return type;
}
}
// No super class/interface extends List.
return null;
}
/**
* Inspects the inheritance hierarchy for the given class and finds the generic type parameter for
* {@link List}.
*
* @param clazz the class to begin the search.
* @param realTypes the array of actual type parameters for {@code clazz}. These will be used to
* substitute generic parameters up the inheritance hierarchy. If {@code clazz} does not have
* any generic parameters, this list should be empty.
* @return the {@link List} parameter.
*/
private static Type getListParameter(Class<?> clazz, Type[] realTypes) {
top:
while (clazz != List.class) {
// First look at generic subclass and interfaces.
Type genericType = getGenericSuperList(clazz);
if (genericType instanceof ParameterizedType) {
// Replace any generic parameters with the real values.
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type[] superArgs = parameterizedType.getActualTypeArguments();
for (int i = 0; i < superArgs.length; ++i) {
Type superArg = superArgs[i];
if (superArg instanceof TypeVariable) {
// Get the type variables for this class so that we can match them to the variables
// used on the super class.
TypeVariable<?>[] clazzParams = clazz.getTypeParameters();
if (realTypes.length != clazzParams.length) {
throw new RuntimeException("Type array mismatch");
}
// Replace the variable parameter with the real type.
boolean foundReplacement = false;
for (int j = 0; j < clazzParams.length; ++j) {
if (superArg == clazzParams[j]) {
Type realType = realTypes[j];
superArgs[i] = realType;
foundReplacement = true;
break;
}
}
if (!foundReplacement) {
throw new RuntimeException("Unable to find replacement for " + superArg);
}
}
}
Class<?> parent = (Class<?>) parameterizedType.getRawType();
realTypes = superArgs;
clazz = parent;
continue;
}
// None of the parameterized types inherit List. Just continue up the inheritance hierarchy
// toward the List interface until we can identify the parameters.
realTypes = EMPTY_TYPES;
for (Class<?> iface : clazz.getInterfaces()) {
if (List.class.isAssignableFrom(iface)) {
clazz = iface;
continue top;
}
}
clazz = clazz.getSuperclass();
}
if (realTypes.length != 1) {
throw new RuntimeException("Unable to identify parameter type for List<T>");
}
return realTypes[0];
}
enum Collection {
SCALAR(false),
VECTOR(true),
PACKED_VECTOR(true),
MAP(false);
private final boolean isList;
Collection(boolean isList) {
this.isList = isList;
}
/** @return the isList */
public boolean isList() {
return isList;
}
}
}

View File

@ -0,0 +1,65 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
/** A factory for message info that is generated into the message itself. */
@ExperimentalApi
class GeneratedMessageInfoFactory implements MessageInfoFactory {
private static final GeneratedMessageInfoFactory instance = new GeneratedMessageInfoFactory();
// Disallow construction - it's a singleton.
private GeneratedMessageInfoFactory() {}
public static GeneratedMessageInfoFactory getInstance() {
return instance;
}
@Override
public boolean isSupported(Class<?> messageType) {
return GeneratedMessageLite.class.isAssignableFrom(messageType);
}
@Override
public MessageInfo messageInfoFor(Class<?> messageType) {
if (!GeneratedMessageLite.class.isAssignableFrom(messageType)) {
throw new IllegalArgumentException("Unsupported message type: " + messageType.getName());
}
try {
return (MessageInfo) GeneratedMessageLite.getDefaultInstance(
messageType.asSubclass(GeneratedMessageLite.class))
.buildMessageInfo();
} catch (Exception e) {
throw new RuntimeException("Unable to get message info for " + messageType.getName(), e);
}
}
}

View File

@ -458,6 +458,29 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
/**
* This class is used to make a generated protected method inaccessible from user's code (e.g.,
* the {@link #newInstance} method below). When this class is used as a parameter's type in a
* generated protected method, the method is visible to user's code in the same package, but
* since the constructor of this class is private to protobuf runtime, user's code can't obtain
* an instance of this class and as such can't actually make a method call on the protected
* method.
*/
protected static final class UnusedPrivateParameter {
static final UnusedPrivateParameter INSTANCE = new UnusedPrivateParameter();
private UnusedPrivateParameter() {
}
}
/**
* Creates a new instance of this message type. Overridden in the generated code.
*/
@SuppressWarnings({"unused"})
protected Object newInstance(UnusedPrivateParameter unused) {
throw new UnsupportedOperationException("This method must be overridden by the subclass.");
}
/**
* Used by parsing constructors in generated classes.
*/

View File

@ -540,6 +540,24 @@ public final class Internal {
}
return valueConverter.doForward(oldValue);
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof Map.Entry)) {
return false;
}
@SuppressWarnings("unchecked")
Map.Entry<?, ?> other = (Map.Entry<?, ?>) o;
return getKey().equals(other.getKey()) && getValue().equals(getValue());
}
@Override
public int hashCode() {
return realEntry.hashCode();
}
}
}

View File

@ -0,0 +1,76 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
/** Enum that identifies the Java types required to store protobuf fields. */
@ExperimentalApi
public enum JavaType {
VOID(Void.class, Void.class, null),
INT(int.class, Integer.class, 0),
LONG(long.class, Long.class, 0L),
FLOAT(float.class, Float.class, 0F),
DOUBLE(double.class, Double.class, 0D),
BOOLEAN(boolean.class, Boolean.class, false),
STRING(String.class, String.class, ""),
BYTE_STRING(ByteString.class, ByteString.class, ByteString.EMPTY),
ENUM(int.class, Integer.class, null),
MESSAGE(Object.class, Object.class, null);
private final Class<?> type;
private final Class<?> boxedType;
private final Object defaultDefault;
JavaType(Class<?> type, Class<?> boxedType, Object defaultDefault) {
this.type = type;
this.boxedType = boxedType;
this.defaultDefault = defaultDefault;
}
/** The default default value for fields of this type, if it's a primitive type. */
public Object getDefaultDefault() {
return defaultDefault;
}
/** Gets the required type for a field that would hold a value of this type. */
public Class<?> getType() {
return type;
}
/** @return the boxedType */
public Class<?> getBoxedType() {
return boxedType;
}
/** Indicates whether or not this {@link JavaType} can be applied to a field of the given type. */
public boolean isValidType(Class<?> t) {
return type.isAssignableFrom(t);
}
}

View File

@ -388,6 +388,18 @@ public class LazyFieldLite {
}
}
/** Writes this lazy field into a {@link Writer}. */
void writeTo(Writer writer, int fieldNumber) throws IOException {
if (memoizedBytes != null) {
writer.writeBytes(fieldNumber, memoizedBytes);
} else if (delayedBytes != null) {
writer.writeBytes(fieldNumber, delayedBytes);
} else if (value != null) {
writer.writeMessage(fieldNumber, value);
} else {
writer.writeBytes(fieldNumber, ByteString.EMPTY);
}
}
/** Might lazily parse the bytes that were previously passed in. Is thread-safe. */
protected void ensureInitialized(MessageLite defaultInstance) {

View File

@ -0,0 +1,190 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.Internal.ProtobufList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Utility class that aids in properly manipulating list fields for either the lite or full runtime.
*/
abstract class ListFieldSchema {
// Disallow construction.
private ListFieldSchema() {}
private static final ListFieldSchema FULL_INSTANCE = new ListFieldSchemaFull();
private static final ListFieldSchema LITE_INSTANCE = new ListFieldSchemaLite();
abstract <L> List<L> mutableListAt(Object msg, long offset);
abstract void makeImmutableListAt(Object msg, long offset);
abstract <L> void mergeListsAt(Object msg, Object otherMsg, long offset);
static ListFieldSchema full() {
return FULL_INSTANCE;
}
static ListFieldSchema lite() {
return LITE_INSTANCE;
}
/** Implementation for the full runtime. */
private static final class ListFieldSchemaFull extends ListFieldSchema {
private static final Class<?> UNMODIFIABLE_LIST_CLASS =
Collections.unmodifiableList(Collections.emptyList()).getClass();
@Override
<L> List<L> mutableListAt(Object message, long offset) {
return mutableListAt(message, offset, AbstractProtobufList.DEFAULT_CAPACITY);
}
@Override
void makeImmutableListAt(Object message, long offset) {
List<?> list = (List<?>) UnsafeUtil.getObject(message, offset);
Object immutable = null;
if (list instanceof LazyStringList) {
immutable = ((LazyStringList) list).getUnmodifiableView();
} else if (UNMODIFIABLE_LIST_CLASS.isAssignableFrom(list.getClass())) {
// already immutable
return;
} else if (list instanceof PrimitiveNonBoxingCollection && list instanceof ProtobufList) {
if (((ProtobufList<?>) list).isModifiable()) {
((ProtobufList<?>) list).makeImmutable();
}
return;
} else {
immutable = Collections.unmodifiableList((List<?>) list);
}
UnsafeUtil.putObject(message, offset, immutable);
}
@SuppressWarnings("unchecked")
private static <L> List<L> mutableListAt(Object message, long offset, int additionalCapacity) {
List<L> list = getList(message, offset);
if (list.isEmpty()) {
if (list instanceof LazyStringList) {
list = (List<L>) new LazyStringArrayList(additionalCapacity);
} else if (list instanceof PrimitiveNonBoxingCollection && list instanceof ProtobufList) {
list = ((ProtobufList<L>) list).mutableCopyWithCapacity(additionalCapacity);
} else {
list = new ArrayList<L>(additionalCapacity);
}
UnsafeUtil.putObject(message, offset, list);
} else if (UNMODIFIABLE_LIST_CLASS.isAssignableFrom(list.getClass())) {
ArrayList<L> newList = new ArrayList<L>(list.size() + additionalCapacity);
newList.addAll(list);
list = newList;
UnsafeUtil.putObject(message, offset, list);
} else if (list instanceof UnmodifiableLazyStringList) {
LazyStringArrayList newList = new LazyStringArrayList(list.size() + additionalCapacity);
newList.addAll((UnmodifiableLazyStringList) list);
list = (List<L>) newList;
UnsafeUtil.putObject(message, offset, list);
} else if (list instanceof PrimitiveNonBoxingCollection
&& list instanceof ProtobufList
&& !((ProtobufList<L>) list).isModifiable()) {
list = ((ProtobufList<L>) list).mutableCopyWithCapacity(list.size() + additionalCapacity);
UnsafeUtil.putObject(message, offset, list);
}
return list;
}
@Override
<E> void mergeListsAt(Object msg, Object otherMsg, long offset) {
List<E> other = getList(otherMsg, offset);
List<E> mine = mutableListAt(msg, offset, other.size());
int size = mine.size();
int otherSize = other.size();
if (size > 0 && otherSize > 0) {
mine.addAll(other);
}
List<E> merged = size > 0 ? mine : other;
UnsafeUtil.putObject(msg, offset, merged);
}
@SuppressWarnings("unchecked")
static <E> List<E> getList(Object message, long offset) {
return (List<E>) UnsafeUtil.getObject(message, offset);
}
}
/** Implementation for the lite runtime. */
private static final class ListFieldSchemaLite extends ListFieldSchema {
@Override
<L> List<L> mutableListAt(Object message, long offset) {
ProtobufList<L> list = getProtobufList(message, offset);
if (!list.isModifiable()) {
int size = list.size();
list =
list.mutableCopyWithCapacity(
size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
UnsafeUtil.putObject(message, offset, list);
}
return list;
}
@Override
void makeImmutableListAt(Object message, long offset) {
ProtobufList<?> list = getProtobufList(message, offset);
list.makeImmutable();
}
@Override
<E> void mergeListsAt(Object msg, Object otherMsg, long offset) {
ProtobufList<E> mine = getProtobufList(msg, offset);
ProtobufList<E> other = getProtobufList(otherMsg, offset);
int size = mine.size();
int otherSize = other.size();
if (size > 0 && otherSize > 0) {
if (!mine.isModifiable()) {
mine = mine.mutableCopyWithCapacity(size + otherSize);
}
mine.addAll(other);
}
ProtobufList<E> merged = size > 0 ? mine : other;
UnsafeUtil.putObject(msg, offset, merged);
}
@SuppressWarnings("unchecked")
static <E> ProtobufList<E> getProtobufList(Object message, long offset) {
return (ProtobufList<E>) UnsafeUtil.getObject(message, offset);
}
}
}

View File

@ -0,0 +1,172 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.Internal.checkNotNull;
/**
* Dynamically generates a manifest-based (i.e. table-based) schema for a given protobuf message.
*/
@ExperimentalApi
final class ManifestSchemaFactory implements SchemaFactory {
private final MessageInfoFactory messageInfoFactory;
public ManifestSchemaFactory() {
this(getDefaultMessageInfoFactory());
}
private ManifestSchemaFactory(MessageInfoFactory messageInfoFactory) {
this.messageInfoFactory = checkNotNull(messageInfoFactory, "messageInfoFactory");
}
@Override
public <T> Schema<T> createSchema(Class<T> messageType) {
SchemaUtil.requireGeneratedMessage(messageType);
MessageInfo messageInfo = messageInfoFactory.messageInfoFor(messageType);
// MessageSet has a special schema.
if (messageInfo.isMessageSetWireFormat()) {
if (GeneratedMessageLite.class.isAssignableFrom(messageType)) {
return MessageSetSchema.newSchema(
SchemaUtil.unknownFieldSetLiteSchema(),
ExtensionSchemas.lite(),
messageInfo.getDefaultInstance());
}
return MessageSetSchema.newSchema(
SchemaUtil.proto2UnknownFieldSetSchema(),
ExtensionSchemas.full(),
messageInfo.getDefaultInstance());
}
return newSchema(messageType, messageInfo);
}
private static <T> Schema<T> newSchema(Class<T> messageType, MessageInfo messageInfo) {
if (GeneratedMessageLite.class.isAssignableFrom(messageType)) {
return isProto2(messageInfo)
? MessageSchema.newSchema(
messageType,
messageInfo,
NewInstanceSchemas.lite(),
ListFieldSchema.lite(),
SchemaUtil.unknownFieldSetLiteSchema(),
ExtensionSchemas.lite(),
MapFieldSchemas.lite())
: MessageSchema.newSchema(
messageType,
messageInfo,
NewInstanceSchemas.lite(),
ListFieldSchema.lite(),
SchemaUtil.unknownFieldSetLiteSchema(),
/* extensionSchema= */ null,
MapFieldSchemas.lite());
}
return isProto2(messageInfo)
? MessageSchema.newSchema(
messageType,
messageInfo,
NewInstanceSchemas.full(),
ListFieldSchema.full(),
SchemaUtil.proto2UnknownFieldSetSchema(),
ExtensionSchemas.full(),
MapFieldSchemas.full())
: MessageSchema.newSchema(
messageType,
messageInfo,
NewInstanceSchemas.full(),
ListFieldSchema.full(),
SchemaUtil.proto3UnknownFieldSetSchema(),
/* extensionSchema= */ null,
MapFieldSchemas.full());
}
private static boolean isProto2(MessageInfo messageInfo) {
return messageInfo.getSyntax() == ProtoSyntax.PROTO2;
}
private static MessageInfoFactory getDefaultMessageInfoFactory() {
return new CompositeMessageInfoFactory(
GeneratedMessageInfoFactory.getInstance(), getDescriptorMessageInfoFactory());
}
private static class CompositeMessageInfoFactory implements MessageInfoFactory {
private MessageInfoFactory[] factories;
CompositeMessageInfoFactory(MessageInfoFactory... factories) {
this.factories = factories;
}
@Override
public boolean isSupported(Class<?> clazz) {
for (MessageInfoFactory factory : factories) {
if (factory.isSupported(clazz)) {
return true;
}
}
return false;
}
@Override
public MessageInfo messageInfoFor(Class<?> clazz) {
for (MessageInfoFactory factory : factories) {
if (factory.isSupported(clazz)) {
return factory.messageInfoFor(clazz);
}
}
throw new UnsupportedOperationException(
"No factory is available for message type: " + clazz.getName());
}
}
private static final MessageInfoFactory EMPTY_FACTORY =
new MessageInfoFactory() {
@Override
public boolean isSupported(Class<?> clazz) {
return false;
}
@Override
public MessageInfo messageInfoFor(Class<?> clazz) {
throw new IllegalStateException("This should never be called.");
}
};
private static MessageInfoFactory getDescriptorMessageInfoFactory() {
try {
Class<?> clazz = Class.forName("com.google.protobuf.DescriptorMessageInfoFactory");
return (MessageInfoFactory) clazz.getDeclaredMethod("getInstance").invoke(null);
} catch (Exception e) {
return EMPTY_FACTORY;
}
}
}

View File

@ -0,0 +1,63 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.util.Map;
interface MapFieldSchema {
/** Returns the map data for mutation. */
Map<?, ?> forMutableMapData(Object mapField);
/** Returns the map data for read. */
Map<?, ?> forMapData(Object mapField);
/** Whether toImmutable() has been called on this map field. */
boolean isImmutable(Object mapField);
/**
* Returns an immutable instance of the map field. It may make the parameter immutable and return
* the parameter, or create an immutable copy. The status of the parameter after the call is
* undefined.
*/
Object toImmutable(Object mapField);
/** Returns a new instance of the map field given a map default entry. */
Object newMapField(Object mapDefaultEntry);
/** Returns the metadata from a default entry. */
MapEntryLite.Metadata<?, ?> forMapMetadata(Object mapDefaultEntry);
/** Merges {@code srcMapField} into {@code destMapField}, and returns the merged instance. */
Object mergeFrom(Object destMapField, Object srcMapField);
/** Compute the serialized size for the map with a given field number. */
int getSerializedSize(int fieldNumber, Object mapField, Object mapDefaultEntry);
}

View File

@ -0,0 +1,112 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.MapEntryLite.Metadata;
import java.util.Map;
class MapFieldSchemaFull implements MapFieldSchema {
@Override
public Map<?, ?> forMutableMapData(Object mapField) {
return ((MapField<?, ?>) mapField).getMutableMap();
}
@Override
public Map<?, ?> forMapData(Object mapField) {
return ((MapField<?, ?>) mapField).getMap();
}
@Override
public boolean isImmutable(Object mapField) {
return !((MapField<?, ?>) mapField).isMutable();
}
@Override
public Object toImmutable(Object mapField) {
((MapField<?, ?>) mapField).makeImmutable();
return mapField;
}
@Override
public Object newMapField(Object mapDefaultEntry) {
return MapField.newMapField((MapEntry<?, ?>) mapDefaultEntry);
}
@Override
public Metadata<?, ?> forMapMetadata(Object mapDefaultEntry) {
return ((MapEntry<?, ?>) mapDefaultEntry).getMetadata();
}
@Override
public Object mergeFrom(Object destMapField, Object srcMapField) {
return mergeFromFull(destMapField, srcMapField);
}
@SuppressWarnings("unchecked")
private static <K, V> Object mergeFromFull(Object destMapField, Object srcMapField) {
MapField<K, V> mine = (MapField<K, V>) destMapField;
MapField<K, V> other = (MapField<K, V>) srcMapField;
if (!mine.isMutable()) {
mine.copy();
}
mine.mergeFrom(other);
return mine;
}
@Override
public int getSerializedSize(int number, Object mapField, Object mapDefaultEntry) {
return getSerializedSizeFull(number, mapField, mapDefaultEntry);
}
@SuppressWarnings("unchecked")
private static <K, V> int getSerializedSizeFull(
int number, Object mapField, Object defaultEntryObject) {
// Full runtime allocates map fields lazily.
if (mapField == null) {
return 0;
}
Map<K, V> map = ((MapField<K, V>) mapField).getMap();
MapEntry<K, V> defaultEntry = (MapEntry<K, V>) defaultEntryObject;
if (map.isEmpty()) {
return 0;
}
int size = 0;
for (Map.Entry<K, V> entry : map.entrySet()) {
size +=
CodedOutputStream.computeTagSize(number)
+ CodedOutputStream.computeLengthDelimitedFieldSize(
MapEntryLite.computeSerializedSize(
defaultEntry.getMetadata(), entry.getKey(), entry.getValue()));
}
return size;
}
}

View File

@ -0,0 +1,107 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.MapEntryLite.Metadata;
import java.util.Map;
class MapFieldSchemaLite implements MapFieldSchema {
@Override
public Map<?, ?> forMutableMapData(Object mapField) {
return (MapFieldLite<?, ?>) mapField;
}
@Override
public Metadata<?, ?> forMapMetadata(Object mapDefaultEntry) {
return ((MapEntryLite<?, ?>) mapDefaultEntry).getMetadata();
}
@Override
public Map<?, ?> forMapData(Object mapField) {
return (MapFieldLite<?, ?>) mapField;
}
@Override
public boolean isImmutable(Object mapField) {
return !((MapFieldLite<?, ?>) mapField).isMutable();
}
@Override
public Object toImmutable(Object mapField) {
((MapFieldLite<?, ?>) mapField).makeImmutable();
return mapField;
}
@Override
public Object newMapField(Object unused) {
return MapFieldLite.emptyMapField().mutableCopy();
}
@Override
public Object mergeFrom(Object destMapField, Object srcMapField) {
return mergeFromLite(destMapField, srcMapField);
}
@SuppressWarnings("unchecked")
private static <K, V> MapFieldLite<K, V> mergeFromLite(Object destMapField, Object srcMapField) {
MapFieldLite<K, V> mine = (MapFieldLite<K, V>) destMapField;
MapFieldLite<K, V> other = (MapFieldLite<K, V>) srcMapField;
if (!other.isEmpty()) {
if (!mine.isMutable()) {
mine = mine.mutableCopy();
}
mine.mergeFrom(other);
}
return mine;
}
@Override
public int getSerializedSize(int fieldNumber, Object mapField, Object mapDefaultEntry) {
return getSerializedSizeLite(fieldNumber, mapField, mapDefaultEntry);
}
@SuppressWarnings("unchecked")
private static <K, V> int getSerializedSizeLite(
int fieldNumber, Object mapField, Object defaultEntry) {
MapFieldLite<K, V> mapFieldLite = (MapFieldLite<K, V>) mapField;
MapEntryLite<K, V> defaultEntryLite = (MapEntryLite<K, V>) defaultEntry;
if (mapFieldLite.isEmpty()) {
return 0;
}
int size = 0;
for (Map.Entry<K, V> entry : mapFieldLite.entrySet()) {
size += defaultEntryLite.computeMessageSize(fieldNumber, entry.getKey(), entry.getValue());
}
return size;
}
}

View File

@ -0,0 +1,53 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
final class MapFieldSchemas {
private static final MapFieldSchema FULL_SCHEMA = loadSchemaForFullRuntime();
private static final MapFieldSchema LITE_SCHEMA = new MapFieldSchemaLite();
static MapFieldSchema full() {
return FULL_SCHEMA;
}
static MapFieldSchema lite() {
return LITE_SCHEMA;
}
private static MapFieldSchema loadSchemaForFullRuntime() {
try {
Class<?> clazz = Class.forName("com.google.protobuf.MapFieldSchemaFull");
return (MapFieldSchema) clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
return null;
}
}
}

View File

@ -0,0 +1,43 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
/** A MesageInfo object describes a proto message type. */
interface MessageInfo {
/** Gets syntax for this type. */
ProtoSyntax getSyntax();
/** Whether this type is MessageSet. */
boolean isMessageSetWireFormat();
/** Gets the default instance of this type. */
MessageLite getDefaultInstance();
}

View File

@ -0,0 +1,41 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
/** A factory that creates {@link MessageInfo} instances for message types. */
@ExperimentalApi
interface MessageInfoFactory {
/** Whether the message class is supported by this factory. */
boolean isSupported(Class<?> clazz);
/** Returns a information of the message class. */
MessageInfo messageInfoFor(Class<?> clazz);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,392 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map.Entry;
/** Schema used for proto2 messages using message_set_wireformat. */
final class MessageSetSchema<T> implements Schema<T> {
private final MessageLite defaultInstance;
private final UnknownFieldSchema<?, ?> unknownFieldSchema;
private final boolean hasExtensions;
private final ExtensionSchema<?> extensionSchema;
private MessageSetSchema(
UnknownFieldSchema<?, ?> unknownFieldSchema,
ExtensionSchema<?> extensionSchema,
MessageLite defaultInstance) {
this.unknownFieldSchema = unknownFieldSchema;
this.hasExtensions = extensionSchema.hasExtensions(defaultInstance);
this.extensionSchema = extensionSchema;
this.defaultInstance = defaultInstance;
}
static <T> MessageSetSchema<T> newSchema(
UnknownFieldSchema<?, ?> unknownFieldSchema,
ExtensionSchema<?> extensionSchema,
MessageLite defaultInstance) {
return new MessageSetSchema<T>(unknownFieldSchema, extensionSchema, defaultInstance);
}
@SuppressWarnings("unchecked")
@Override
public T newInstance() {
return (T) defaultInstance.newBuilderForType().buildPartial();
}
@Override
public boolean equals(T message, T other) {
Object messageUnknown = unknownFieldSchema.getFromMessage(message);
Object otherUnknown = unknownFieldSchema.getFromMessage(other);
if (!messageUnknown.equals(otherUnknown)) {
return false;
}
if (hasExtensions) {
FieldSet<?> messageExtensions = extensionSchema.getExtensions(message);
FieldSet<?> otherExtensions = extensionSchema.getExtensions(other);
return messageExtensions.equals(otherExtensions);
}
return true;
}
@Override
public int hashCode(T message) {
int hashCode = unknownFieldSchema.getFromMessage(message).hashCode();
if (hasExtensions) {
FieldSet<?> extensions = extensionSchema.getExtensions(message);
hashCode = (hashCode * 53) + extensions.hashCode();
}
return hashCode;
}
@Override
public void mergeFrom(T message, T other) {
SchemaUtil.mergeUnknownFields(unknownFieldSchema, message, other);
if (hasExtensions) {
SchemaUtil.mergeExtensions(extensionSchema, message, other);
}
}
@SuppressWarnings("unchecked")
@Override
public void writeTo(T message, Writer writer) throws IOException {
FieldSet<?> extensions = extensionSchema.getExtensions(message);
Iterator<?> iterator = extensions.iterator();
while (iterator.hasNext()) {
Entry<?, ?> extension = (Entry<?, ?>) iterator.next();
FieldSet.FieldDescriptorLite<?> fd = (FieldSet.FieldDescriptorLite<?>) extension.getKey();
if (fd.getLiteJavaType() != WireFormat.JavaType.MESSAGE || fd.isRepeated() || fd.isPacked()) {
throw new IllegalStateException("Found invalid MessageSet item.");
}
if (extension instanceof LazyField.LazyEntry) {
writer.writeMessageSetItem(
fd.getNumber(), ((LazyField.LazyEntry) extension).getField().toByteString());
} else {
writer.writeMessageSetItem(fd.getNumber(), extension.getValue());
}
}
writeUnknownFieldsHelper(unknownFieldSchema, message, writer);
}
/**
* A helper method for wildcard capture of {@code unknownFieldSchema}. See:
* https://docs.oracle.com/javase/tutorial/java/generics/capture.html
*/
private <UT, UB> void writeUnknownFieldsHelper(
UnknownFieldSchema<UT, UB> unknownFieldSchema, T message, Writer writer) throws IOException {
unknownFieldSchema.writeAsMessageSetTo(unknownFieldSchema.getFromMessage(message), writer);
}
@SuppressWarnings("ReferenceEquality")
@Override
public void mergeFrom(
T message, byte[] data, int position, int limit, ArrayDecoders.Registers registers)
throws IOException {
UnknownFieldSetLite unknownFields = ((GeneratedMessageLite) message).unknownFields;
if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = UnknownFieldSetLite.newInstance();
((GeneratedMessageLite) message).unknownFields = unknownFields;
}
final FieldSet<GeneratedMessageLite.ExtensionDescriptor> extensions =
((GeneratedMessageLite.ExtendableMessage<?, ?>) message).ensureExtensionsAreMutable();
GeneratedMessageLite.GeneratedExtension<?, ?> extension = null;
while (position < limit) {
position = ArrayDecoders.decodeVarint32(data, position, registers);
final int startTag = registers.int1;
if (startTag != WireFormat.MESSAGE_SET_ITEM_TAG) {
if (WireFormat.getTagWireType(startTag) == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
extension =
(GeneratedMessageLite.GeneratedExtension<?, ?>) extensionSchema.findExtensionByNumber(
registers.extensionRegistry, defaultInstance,
WireFormat.getTagFieldNumber(startTag));
if (extension != null) {
position =
ArrayDecoders.decodeMessageField(
Protobuf.getInstance().schemaFor(
extension.getMessageDefaultInstance().getClass()),
data, position, limit, registers);
extensions.setField(extension.descriptor, registers.object1);
} else {
position =
ArrayDecoders.decodeUnknownField(
startTag, data, position, limit, unknownFields, registers);
}
} else {
position = ArrayDecoders.skipField(startTag, data, position, limit, registers);
}
continue;
}
int typeId = 0;
ByteString rawBytes = null;
while (position < limit) {
position = ArrayDecoders.decodeVarint32(data, position, registers);
final int tag = registers.int1;
final int number = WireFormat.getTagFieldNumber(tag);
final int wireType = WireFormat.getTagWireType(tag);
switch (number) {
case WireFormat.MESSAGE_SET_TYPE_ID:
if (wireType == WireFormat.WIRETYPE_VARINT) {
position = ArrayDecoders.decodeVarint32(data, position, registers);
typeId = registers.int1;
extension =
(GeneratedMessageLite.GeneratedExtension<?, ?>) extensionSchema
.findExtensionByNumber(registers.extensionRegistry, defaultInstance, typeId);
continue;
}
break;
case WireFormat.MESSAGE_SET_MESSAGE:
if (extension != null) {
position = ArrayDecoders.decodeMessageField(
Protobuf.getInstance().schemaFor(
extension.getMessageDefaultInstance().getClass()),
data, position, limit, registers);
extensions.setField(extension.descriptor, registers.object1);
continue;
} else {
if (wireType == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
position = ArrayDecoders.decodeBytes(data, position, registers);
rawBytes = (ByteString) registers.object1;
continue;
}
break;
}
default:
break;
}
if (tag == WireFormat.MESSAGE_SET_ITEM_END_TAG) {
break;
}
position = ArrayDecoders.skipField(tag, data, position, limit, registers);
}
if (rawBytes != null) {
unknownFields.storeField(
WireFormat.makeTag(typeId, WireFormat.WIRETYPE_LENGTH_DELIMITED), rawBytes);
}
}
if (position != limit) {
throw InvalidProtocolBufferException.parseFailure();
}
}
@Override
public void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
throws IOException {
mergeFromHelper(unknownFieldSchema, extensionSchema, message, reader, extensionRegistry);
}
/**
* A helper method for wildcard capture of {@code unknownFieldSchema}. See:
* https://docs.oracle.com/javase/tutorial/java/generics/capture.html
*/
@SuppressWarnings("unchecked")
private <UT, UB, ET extends FieldSet.FieldDescriptorLite<ET>> void mergeFromHelper(
UnknownFieldSchema<UT, UB> unknownFieldSchema,
ExtensionSchema<ET> extensionSchema,
T message,
Reader reader,
ExtensionRegistryLite extensionRegistry)
throws IOException {
UB unknownFields = unknownFieldSchema.getBuilderFromMessage(message);
FieldSet<ET> extensions = extensionSchema.getMutableExtensions(message);
try {
while (true) {
final int number = reader.getFieldNumber();
if (number == Reader.READ_DONE) {
return;
}
if (parseMessageSetItemOrUnknownField(
reader,
extensionRegistry,
extensionSchema,
extensions,
unknownFieldSchema,
unknownFields)) {
continue;
}
// Done reading.
return;
}
} finally {
unknownFieldSchema.setBuilderToMessage(message, unknownFields);
}
}
@Override
public void makeImmutable(T message) {
unknownFieldSchema.makeImmutable(message);
extensionSchema.makeImmutable(message);
}
private <UT, UB, ET extends FieldSet.FieldDescriptorLite<ET>>
boolean parseMessageSetItemOrUnknownField(
Reader reader,
ExtensionRegistryLite extensionRegistry,
ExtensionSchema<ET> extensionSchema,
FieldSet<ET> extensions,
UnknownFieldSchema<UT, UB> unknownFieldSchema,
UB unknownFields)
throws IOException {
int startTag = reader.getTag();
if (startTag != WireFormat.MESSAGE_SET_ITEM_TAG) {
if (WireFormat.getTagWireType(startTag) == WireFormat.WIRETYPE_LENGTH_DELIMITED) {
Object extension =
extensionSchema.findExtensionByNumber(
extensionRegistry, defaultInstance, WireFormat.getTagFieldNumber(startTag));
if (extension != null) {
extensionSchema.parseLengthPrefixedMessageSetItem(
reader, extension, extensionRegistry, extensions);
return true;
} else {
return unknownFieldSchema.mergeOneFieldFrom(unknownFields, reader);
}
} else {
return reader.skipField();
}
}
// The wire format for MessageSet is:
// message MessageSet {
// repeated group Item = 1 {
// required int32 typeId = 2;
// required bytes message = 3;
// }
// }
// "typeId" is the extension's field number. The extension can only be
// a message type, where "message" contains the encoded bytes of that
// message.
//
// In practice, we will probably never see a MessageSet item in which
// the message appears before the type ID, or where either field does not
// appear exactly once. However, in theory such cases are valid, so we
// should be prepared to accept them.
int typeId = 0;
ByteString rawBytes = null; // If we encounter "message" before "typeId"
Object extension = null;
// Read bytes from input, if we get it's type first then parse it eagerly,
// otherwise we store the raw bytes in a local variable.
loop:
while (true) {
final int number = reader.getFieldNumber();
if (number == Reader.READ_DONE) {
break;
}
final int tag = reader.getTag();
if (tag == WireFormat.MESSAGE_SET_TYPE_ID_TAG) {
typeId = reader.readUInt32();
extension =
extensionSchema.findExtensionByNumber(extensionRegistry, defaultInstance, typeId);
continue;
} else if (tag == WireFormat.MESSAGE_SET_MESSAGE_TAG) {
if (extension != null) {
extensionSchema.parseLengthPrefixedMessageSetItem(
reader, extension, extensionRegistry, extensions);
continue;
}
// We haven't seen a type ID yet or we want parse message lazily.
rawBytes = reader.readBytes();
continue;
} else {
if (!reader.skipField()) {
break loop; // End of group
}
}
}
if (reader.getTag() != WireFormat.MESSAGE_SET_ITEM_END_TAG) {
throw InvalidProtocolBufferException.invalidEndTag();
}
// If there are any rawBytes left, it means the message content appears before the type ID.
if (rawBytes != null) {
if (extension != null) { // We known the type
// TODO(xiaofeng): Instead of reading into a temporary ByteString, maybe there is a way
// to read directly from Reader to the submessage?
extensionSchema.parseMessageSetItem(rawBytes, extension, extensionRegistry, extensions);
} else {
unknownFieldSchema.addLengthDelimited(unknownFields, typeId, rawBytes);
}
}
return true;
}
@Override
public final boolean isInitialized(T message) {
FieldSet<?> extensions = extensionSchema.getExtensions(message);
return extensions.isInitialized();
}
@Override
public int getSerializedSize(T message) {
int size = 0;
size += getUnknownFieldsSerializedSize(unknownFieldSchema, message);
if (hasExtensions) {
size += extensionSchema.getExtensions(message).getMessageSetSerializedSize();
}
return size;
}
private <UT, UB> int getUnknownFieldsSerializedSize(
UnknownFieldSchema<UT, UB> schema, T message) {
UT unknowns = schema.getFromMessage(message);
return schema.getSerializedSizeAsMessageSet(unknowns);
}
}

View File

@ -0,0 +1,36 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
interface NewInstanceSchema {
/** Create a new message instance given the default instance of the message type. */
Object newInstance(Object defaultInstance);
}

View File

@ -0,0 +1,39 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
final class NewInstanceSchemaFull implements NewInstanceSchema {
@Override
public Object newInstance(Object defaultInstance) {
return ((GeneratedMessageV3) defaultInstance)
.newInstance(GeneratedMessageV3.UnusedPrivateParameter.INSTANCE);
}
}

View File

@ -0,0 +1,39 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
final class NewInstanceSchemaLite implements NewInstanceSchema {
@Override
public Object newInstance(Object defaultInstance) {
return ((GeneratedMessageLite) defaultInstance)
.dynamicMethod(GeneratedMessageLite.MethodToInvoke.NEW_MUTABLE_INSTANCE);
}
}

View File

@ -0,0 +1,53 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
final class NewInstanceSchemas {
private static final NewInstanceSchema FULL_SCHEMA = loadSchemaForFullRuntime();
private static final NewInstanceSchema LITE_SCHEMA = new NewInstanceSchemaLite();
static NewInstanceSchema full() {
return FULL_SCHEMA;
}
static NewInstanceSchema lite() {
return LITE_SCHEMA;
}
private static NewInstanceSchema loadSchemaForFullRuntime() {
try {
Class<?> clazz = Class.forName("com.google.protobuf.NewInstanceSchemaFull");
return (NewInstanceSchema) clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) {
return null;
}
}
}

View File

@ -0,0 +1,66 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.lang.reflect.Field;
/** Information for a oneof within a protobuf message. */
// TODO(nathanmittler): make this private once all of experimental code is migrated to protobuf.
@ExperimentalApi
final class OneofInfo {
private final int id;
private final Field caseField;
private final Field valueField;
public OneofInfo(int id, Field caseField, Field valueField) {
this.id = id;
this.caseField = caseField;
this.valueField = valueField;
}
/**
* Returns the unique identifier of the oneof within the message. This is really just an index
* starting at zero.
*/
public int getId() {
return id;
}
/** The {@code int} field containing the field number of the currently active member. */
public Field getCaseField() {
return caseField;
}
/** The {@link Object} field containing the value of the currently active member. */
public Field getValueField() {
return valueField;
}
}

View File

@ -0,0 +1,38 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
/** Represents the syntax version of the message. */
@ExperimentalApi
public enum ProtoSyntax {
PROTO2,
PROTO3;
}

View File

@ -0,0 +1,152 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.Internal.checkNotNull;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* Main runtime interface for protobuf. Applications should interact with this interface (rather
* than directly accessing internal APIs) in order to perform operations on protobuf messages.
*/
@ExperimentalApi
final class Protobuf {
private static final Protobuf INSTANCE = new Protobuf();
private final SchemaFactory schemaFactory;
// TODO(nathanmittler): Consider using ClassValue instead.
private final ConcurrentMap<Class<?>, Schema<?>> schemaCache =
new ConcurrentHashMap<Class<?>, Schema<?>>();
/** Gets the singleton instance of the Protobuf runtime. */
public static Protobuf getInstance() {
return INSTANCE;
}
/** Writes the given message to the target {@link Writer}. */
public <T> void writeTo(T message, Writer writer) throws IOException {
schemaFor(message).writeTo(message, writer);
}
/** Reads fields from the given {@link Reader} and merges them into the message. */
public <T> void mergeFrom(T message, Reader reader) throws IOException {
mergeFrom(message, reader, ExtensionRegistryLite.getEmptyRegistry());
}
/** Reads fields from the given {@link Reader} and merges them into the message. */
public <T> void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
throws IOException {
schemaFor(message).mergeFrom(message, reader, extensionRegistry);
}
/** Marks repeated/map/extension/unknown fields as immutable. */
public <T> void makeImmutable(T message) {
schemaFor(message).makeImmutable(message);
}
/**
* Checks if all required fields are set. TODO(xiaofeng): Make this package private when the tests
* are moved to protobuf package.
*/
public <T> boolean isInitialized(T message) {
return schemaFor(message).isInitialized(message);
}
/** Gets the schema for the given message type. */
public <T> Schema<T> schemaFor(Class<T> messageType) {
checkNotNull(messageType, "messageType");
@SuppressWarnings("unchecked")
Schema<T> schema = (Schema<T>) schemaCache.get(messageType);
if (schema == null) {
schema = schemaFactory.createSchema(messageType);
@SuppressWarnings("unchecked")
Schema<T> previous = (Schema<T>) registerSchema(messageType, schema);
if (previous != null) {
// A new schema was registered by another thread.
schema = previous;
}
}
return schema;
}
/** Gets the schema for the given message. */
@SuppressWarnings("unchecked")
public <T> Schema<T> schemaFor(T message) {
return schemaFor((Class<T>) message.getClass());
}
/**
* Registers the given schema for the message type only if a schema was not already registered.
*
* @param messageType the type of message on which the schema operates.
* @param schema the schema for the message type.
* @return the previously registered schema, or {@code null} if the given schema was successfully
* registered.
*/
public Schema<?> registerSchema(Class<?> messageType, Schema<?> schema) {
checkNotNull(messageType, "messageType");
checkNotNull(schema, "schema");
return schemaCache.putIfAbsent(messageType, schema);
}
/**
* Visible for testing only. Registers the given schema for the message type. If a schema was
* previously registered, it will be replaced by the provided schema.
*
* @param messageType the type of message on which the schema operates.
* @param schema the schema for the message type.
* @return the previously registered schema, or {@code null} if no schema was registered
* previously.
*/
public Schema<?> registerSchemaOverride(Class<?> messageType, Schema<?> schema) {
checkNotNull(messageType, "messageType");
checkNotNull(schema, "schema");
return schemaCache.put(messageType, schema);
}
private Protobuf() {
schemaFactory = new ManifestSchemaFactory();
}
int getTotalSchemaSize() {
int result = 0;
for (Schema<?> schema : schemaCache.values()) {
if (schema instanceof MessageSchema) {
result += ((MessageSchema) schema).getSchemaSize();
}
}
return result;
}
}

View File

@ -0,0 +1,94 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.Internal.BooleanList;
import com.google.protobuf.Internal.DoubleList;
import com.google.protobuf.Internal.FloatList;
import com.google.protobuf.Internal.IntList;
import com.google.protobuf.Internal.LongList;
import com.google.protobuf.Internal.ProtobufList;
/** Utility class for construction of lists that extend {@link ProtobufList}. */
@ExperimentalApi
final class ProtobufLists {
private ProtobufLists() {}
public static <E> ProtobufList<E> emptyProtobufList() {
return ProtobufArrayList.emptyList();
}
public static <E> ProtobufList<E> mutableCopy(ProtobufList<E> list) {
int size = list.size();
return list.mutableCopyWithCapacity(
size == 0 ? AbstractProtobufList.DEFAULT_CAPACITY : size * 2);
}
public static BooleanList emptyBooleanList() {
return BooleanArrayList.emptyList();
}
public static BooleanList newBooleanList() {
return new BooleanArrayList();
}
public static IntList emptyIntList() {
return IntArrayList.emptyList();
}
public static IntList newIntList() {
return new IntArrayList();
}
public static LongList emptyLongList() {
return LongArrayList.emptyList();
}
public static LongList newLongList() {
return new LongArrayList();
}
public static FloatList emptyFloatList() {
return FloatArrayList.emptyList();
}
public static FloatList newFloatList() {
return new FloatArrayList();
}
public static DoubleList emptyDoubleList() {
return DoubleArrayList.emptyList();
}
public static DoubleList newDoubleList() {
return new DoubleArrayList();
}
}

View File

@ -0,0 +1,220 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
/**
* RawMessageInfo stores the same amount of information as {@link MessageInfo} but in a more compact
* format.
*/
final class RawMessageInfo implements MessageInfo {
private final MessageLite defaultInstance;
/**
* The compact format packs everything in a String object and a Object[] array. The String object
* is encoded with field number, field type, hasbits offset, oneof index, etc., whereas the
* Object[] array contains field references, class references, instance references, etc.
*
* <p>The String object encodes a sequence of integers into UTF-16 characters. For each int, it
* will be encoding into 1 to 3 UTF-16 characters depending on its unsigned value:
*
* <ul>
* <li>1 char: [c1: 0x0000 - 0xD7FF] = int of the same value.
* <li>2 chars: [c1: 0xE000 - 0xFFFF], [c2: 0x0000 - 0xD7FF] = (c2 << 13) | (c1 & 0x1FFF)
* <li>3 chars: [c1: 0xE000 - 0xFFFF], [c2: 0xE000 - 0xFFFF], [c3: 0x0000 - 0xD7FF] = (c3 << 26)
* | ((c2 & 0x1FFF) << 13) | (c1 & 0x1FFF)
* </ul>
*
* <p>Note that we don't use UTF-16 surrogate pairs [0xD800 - 0xDFFF] because they have to come in
* pairs to form a valid UTF-16char sequence and don't help us encode values more efficiently.
*
* <p>The integer sequence encoded in the String object has the following layout:
*
* <ul>
* <li>[0]: flags, flags & 0x1 = is proto2?, flags & 0x2 = is message?.
* <li>[1]: field count, if 0, this is the end of the integer sequence and the corresponding
* Object[] array should be null.
* <li>[2]: oneof count
* <li>[3]: hasbits count, how many hasbits integers are generated.
* <li>[4]: min field number
* <li>[5]: max field number
* <li>[6]: total number of entries need to allocate
* <li>[7]: map field count
* <li>[8]: repeated field count, this doesn't include map fields.
* <li>[9]: size of checkInitialized array
* <li>[...]: field entries
* </ul>
*
* <p>Each field entry starts with a field number and the field type:
*
* <ul>
* <li>[0]: field number
* <li>[1]: field type with extra bits:
* <ul>
* <li>v & 0xFF = field type as defined in the FieldType class
* <li>v & 0x100 = is required?
* <li>v & 0x200 = is checkUtf8?
* <li>v & 0x400 = needs isInitialized check?
* <li>v & 0x800 = is map field with proto2 enum value?
* </ul>
* </ul>
*
* If the file is proto2 and this is a singular field:
*
* <ul>
* <li>[2]: hasbits offset
* </ul>
*
* If the field is in an oneof:
*
* <ul>
* <li>[2]: oenof index
* </ul>
*
* For other types, the field entry only has field number and field type.
*
* <p>The Object[] array has 3 sections:
*
* <ul>
* <li>---- oneof section ----
* <ul>
* <li>[0]: value field for oneof 1.
* <li>[1]: case field for oneof 1.
* <li>...
* <li>[.]: value field for oneof n.
* <li>[.]: case field for oneof n.
* </ul>
* <li>---- hasbits section ----
* <ul>
* <li>[.]: hasbits field 1
* <li>[.]: hasbits field 2
* <li>...
* <li>[.]: hasbits field n
* </ul>
* <li>---- field section ----
* <ul>
* <li>[...]: field entries
* </ul>
* </ul>
*
* <p>In the Object[] array, field entries are ordered in the same way as field entries in the
* String object. The size of each entry is determined by the field type.
*
* <ul>
* <li>Oneof field:
* <ul>
* <li>Oneof message field:
* <ul>
* <li>[0]: message class reference.
* </ul>
* <li>Oneof enum fieldin proto2:
* <ul>
* <li>[0]: EnumLiteMap
* </ul>
* <li>For all other oneof fields, field entry in the Object[] array is empty.
* </ul>
* <li>Repeated message field:
* <ul>
* <li>[0]: field reference
* <li>[1]: message class reference
* </ul>
* <li>Proto2 singular/repeated enum field:
* <ul>
* <li>[0]: field reference
* <li>[1]: EnumLiteMap
* </ul>
* <li>Map field with a proto2 enum value:
* <ul>
* <li>[0]: field reference
* <li>[1]: map default entry instance
* <li>[2]: EnumLiteMap
* </ul>
* <li>Map field with other value types:
* <ul>
* <li>[0]: field reference
* <li>[1]: map default entry instance
* </ul>
* <li>All other field type:
* <ul>
* <li>[0]: field reference
* </ul>
* </ul>
*
* <p>In order to read the field info from this compact format, a reader needs to progress through
* the String object and the Object[] array simultaneously.
*/
private final String info;
private final Object[] objects;
private final int flags;
RawMessageInfo(MessageLite defaultInstance, String info, Object[] objects) {
this.defaultInstance = defaultInstance;
this.info = info;
this.objects = objects;
int position = 0;
int value = (int) info.charAt(position++);
if (value < 0xD800) {
flags = value;
} else {
int result = value & 0x1FFF;
int shift = 13;
while ((value = info.charAt(position++)) >= 0xD800) {
result |= (value & 0x1FFF) << shift;
shift += 13;
}
flags = result | (value << shift);
}
}
String getStringInfo() {
return info;
}
Object[] getObjects() {
return objects;
}
@Override
public MessageLite getDefaultInstance() {
return defaultInstance;
}
@Override
public ProtoSyntax getSyntax() {
return (flags & 0x1) == 0x1 ? ProtoSyntax.PROTO2 : ProtoSyntax.PROTO3;
}
@Override
public boolean isMessageSetWireFormat() {
return (flags & 0x2) == 0x2;
}
}

View File

@ -0,0 +1,379 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/** A reader of fields from a serialized protobuf message. */
// TODO(nathanmittler): Refactor to allow the reader to allocate properly sized lists.
@ExperimentalApi
interface Reader {
/** Value used to indicate that the end of input has been reached. */
int READ_DONE = Integer.MAX_VALUE;
/** Value used to indicate that the reader does not know the tag about the field. */
int TAG_UNKNOWN = 0;
boolean shouldDiscardUnknownFields();
/**
* Gets the field number for the current field being read.
*
* <p>TODO(liujisi): Rename it to make it more explicit about the side effect on the underlying
* buffer.
*
* @return the current field number or {@link #READ_DONE} if the end of input has been reached.
*/
int getFieldNumber() throws IOException;
/**
* Gets the wire tag of the current field.
*
* @return the current wire tag or {@link #TAG_UNKNOWN} if the reader does not know the tag of the
* current field.
*/
int getTag();
/**
* Skips the current field and advances the reader to the next field.
*
* @return {@code true} if there are more fields or {@code false} if the end of input has been
* reached.
*/
boolean skipField() throws IOException;
/**
* Reads and returns the next field of type {@code DOUBLE} and advances the reader to the next
* field.
*/
double readDouble() throws IOException;
/**
* Reads and returns the next field of type {@code FLOAT} and advances the reader to the next
* field.
*/
float readFloat() throws IOException;
/**
* Reads and returns the next field of type {@code UINT64} and advances the reader to the next
* field.
*/
long readUInt64() throws IOException;
/**
* Reads and returns the next field of type {@code INT64} and advances the reader to the next
* field.
*/
long readInt64() throws IOException;
/**
* Reads and returns the next field of type {@code INT32} and advances the reader to the next
* field.
*/
int readInt32() throws IOException;
/**
* Reads and returns the next field of type {@code FIXED64} and advances the reader to the next
* field.
*/
long readFixed64() throws IOException;
/**
* Reads and returns the next field of type {@code FIXED32} and advances the reader to the next
* field.
*/
int readFixed32() throws IOException;
/**
* Reads and returns the next field of type {@code BOOL} and advances the reader to the next
* field.
*/
boolean readBool() throws IOException;
/**
* Reads and returns the next field of type {@code STRING} and advances the reader to the next
* field. If the stream contains malformed UTF-8, replace the offending bytes with the standard
* UTF-8 replacement character.
*/
String readString() throws IOException;
/**
* Reads and returns the next field of type {@code STRING} and advances the reader to the next
* field. If the stream contains malformed UTF-8, throw exception {@link
* InvalidProtocolBufferException}.
*/
String readStringRequireUtf8() throws IOException;
// TODO(yilunchong): the lack of other opinions for whether to expose this on the interface
<T> T readMessageBySchemaWithCheck(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException;
/**
* Reads and returns the next field of type {@code MESSAGE} and advances the reader to the next
* field.
*/
<T> T readMessage(Class<T> clazz, ExtensionRegistryLite extensionRegistry) throws IOException;
/**
* Reads and returns the next field of type {@code GROUP} and advances the reader to the next
* field.
*
* @deprecated groups fields are deprecated.
*/
@Deprecated
<T> T readGroup(Class<T> clazz, ExtensionRegistryLite extensionRegistry) throws IOException;
// TODO(yilunchong): the lack of other opinions for whether to expose this on the interface
@Deprecated
<T> T readGroupBySchemaWithCheck(Schema<T> schema, ExtensionRegistryLite extensionRegistry)
throws IOException;
/**
* Reads and returns the next field of type {@code BYTES} and advances the reader to the next
* field.
*/
ByteString readBytes() throws IOException;
/**
* Reads and returns the next field of type {@code UINT32} and advances the reader to the next
* field.
*/
int readUInt32() throws IOException;
/**
* Reads and returns the next field of type {@code ENUM} and advances the reader to the next
* field.
*/
int readEnum() throws IOException;
/**
* Reads and returns the next field of type {@code SFIXED32} and advances the reader to the next
* field.
*/
int readSFixed32() throws IOException;
/**
* Reads and returns the next field of type {@code SFIXED64} and advances the reader to the next
* field.
*/
long readSFixed64() throws IOException;
/**
* Reads and returns the next field of type {@code SINT32} and advances the reader to the next
* field.
*/
int readSInt32() throws IOException;
/**
* Reads and returns the next field of type {@code SINT64} and advances the reader to the next
* field.
*/
long readSInt64() throws IOException;
/**
* Reads the next field of type {@code DOUBLE_LIST} or {@code DOUBLE_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readDoubleList(List<Double> target) throws IOException;
/**
* Reads the next field of type {@code FLOAT_LIST} or {@code FLOAT_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readFloatList(List<Float> target) throws IOException;
/**
* Reads the next field of type {@code UINT64_LIST} or {@code UINT64_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readUInt64List(List<Long> target) throws IOException;
/**
* Reads the next field of type {@code INT64_LIST} or {@code INT64_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readInt64List(List<Long> target) throws IOException;
/**
* Reads the next field of type {@code INT32_LIST} or {@code INT32_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readInt32List(List<Integer> target) throws IOException;
/**
* Reads the next field of type {@code FIXED64_LIST} or {@code FIXED64_LIST_PACKED} and advances
* the reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readFixed64List(List<Long> target) throws IOException;
/**
* Reads the next field of type {@code FIXED32_LIST} or {@code FIXED32_LIST_PACKED} and advances
* the reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readFixed32List(List<Integer> target) throws IOException;
/**
* Reads the next field of type {@code BOOL_LIST} or {@code BOOL_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readBoolList(List<Boolean> target) throws IOException;
/**
* Reads the next field of type {@code STRING_LIST} and advances the reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readStringList(List<String> target) throws IOException;
/**
* Reads the next field of type {@code STRING_LIST} and advances the reader to the next field. If
* the stream contains malformed UTF-8, throw exception {@link InvalidProtocolBufferException}.
*
* @param target the list that will receive the read values.
*/
void readStringListRequireUtf8(List<String> target) throws IOException;
/**
* Reads the next field of type {@code MESSAGE_LIST} and advances the reader to the next field.
*
* @param target the list that will receive the read values.
* @param targetType the type of the elements stored in the {@code target} list.
*/
<T> void readMessageList(
List<T> target, Schema<T> schema, ExtensionRegistryLite extensionRegistry) throws IOException;
<T> void readMessageList(
List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
throws IOException;
/**
* Reads the next field of type {@code GROUP_LIST} and advances the reader to the next field.
*
* @param target the list that will receive the read values.
* @param targetType the type of the elements stored in the {@code target} list.
* @deprecated groups fields are deprecated.
*/
@Deprecated
<T> void readGroupList(
List<T> target, Class<T> targetType, ExtensionRegistryLite extensionRegistry)
throws IOException;
@Deprecated
<T> void readGroupList(
List<T> target, Schema<T> targetType, ExtensionRegistryLite extensionRegistry)
throws IOException;
/**
* Reads the next field of type {@code BYTES_LIST} and advances the reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readBytesList(List<ByteString> target) throws IOException;
/**
* Reads the next field of type {@code UINT32_LIST} or {@code UINT32_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readUInt32List(List<Integer> target) throws IOException;
/**
* Reads the next field of type {@code ENUM_LIST} or {@code ENUM_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readEnumList(List<Integer> target) throws IOException;
/**
* Reads the next field of type {@code SFIXED32_LIST} or {@code SFIXED32_LIST_PACKED} and advances
* the reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readSFixed32List(List<Integer> target) throws IOException;
/**
* Reads the next field of type {@code SFIXED64_LIST} or {@code SFIXED64_LIST_PACKED} and advances
* the reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readSFixed64List(List<Long> target) throws IOException;
/**
* Reads the next field of type {@code SINT32_LIST} or {@code SINT32_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readSInt32List(List<Integer> target) throws IOException;
/**
* Reads the next field of type {@code SINT64_LIST} or {@code SINT64_LIST_PACKED} and advances the
* reader to the next field.
*
* @param target the list that will receive the read values.
*/
void readSInt64List(List<Long> target) throws IOException;
/**
* Reads the next field of type {@code MAP} and advances the reader to the next field.
*
* @param target the mutable map that will receive the read values.
* @param mapDefaultEntry the default entry of the map field.
* @param extensionRegistry the extension registry for parsing message value fields.
*/
<K, V> void readMap(
Map<K, V> target,
MapEntryLite.Metadata<K, V> mapDefaultEntry,
ExtensionRegistryLite extensionRegistry)
throws IOException;
}

View File

@ -445,6 +445,11 @@ final class RopeByteString extends ByteString {
right.writeTo(output);
}
@Override
void writeToReverse(ByteOutput output) throws IOException {
right.writeToReverse(output);
left.writeToReverse(output);
}
@Override
protected String toStringInternal(Charset charset) {

View File

@ -0,0 +1,85 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.ArrayDecoders.Registers;
import java.io.IOException;
/**
* A runtime schema for a single protobuf message. A schema provides operations on message instances
* such as serialization/deserialization.
*/
@ExperimentalApi
interface Schema<T> {
/** Writes the given message to the target {@link Writer}. */
void writeTo(T message, Writer writer) throws IOException;
/**
* Reads fields from the given {@link Reader} and merges them into the message. It doesn't make
* the message immutable after parsing is done. To make the message immutable, use {@link
* #makeImmutable}.
*/
void mergeFrom(T message, Reader reader, ExtensionRegistryLite extensionRegistry)
throws IOException;
/**
* Like the above but parses from a byte[] without extensions. Entry point of fast path. Note that
* this method may throw IndexOutOfBoundsException if the input data is not valid protobuf wire
* format. Protobuf public API methods should catch and convert that exception to
* InvalidProtocolBufferException.
*/
void mergeFrom(T message, byte[] data, int position, int limit, Registers registers)
throws IOException;
/** Marks repeated/map/extension/unknown fields as immutable. */
void makeImmutable(T message);
/** Checks whether all required fields are set. */
boolean isInitialized(T message);
/** Creates a new instance of the message class. */
T newInstance();
/** Determine of the two messages are equal. */
boolean equals(T message, T other);
/** Compute a hashCode for the message. */
int hashCode(T message);
/**
* Merge values from {@code other} into {@code message}. This method doesn't make the message
* immutable. To make the message immutable after merging, use {@link #makeImmutable}.
*/
void mergeFrom(T message, T other);
/** Compute the serialized size of the message. */
int getSerializedSize(T message);
}

View File

@ -0,0 +1,38 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
/** A factory that manufactures {@link Schema} instances for protobuf messages. */
@ExperimentalApi
interface SchemaFactory {
/** Creates a schema instance for the given protobuf message type. */
<T> Schema<T> createSchema(Class<T> messageType);
}

View File

@ -0,0 +1,991 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.FieldSet.FieldDescriptorLite;
import com.google.protobuf.Internal.EnumLiteMap;
import com.google.protobuf.Internal.EnumVerifier;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.RandomAccess;
/** Helper methods used by schemas. */
@ExperimentalApi
final class SchemaUtil {
private static final Class<?> GENERATED_MESSAGE_CLASS = getGeneratedMessageClass();
private static final UnknownFieldSchema<?, ?> PROTO2_UNKNOWN_FIELD_SET_SCHEMA =
getUnknownFieldSetSchema(false);
private static final UnknownFieldSchema<?, ?> PROTO3_UNKNOWN_FIELD_SET_SCHEMA =
getUnknownFieldSetSchema(true);
private static final UnknownFieldSchema<?, ?> UNKNOWN_FIELD_SET_LITE_SCHEMA =
new UnknownFieldSetLiteSchema();
private static final int DEFAULT_LOOK_UP_START_NUMBER = 40;
private SchemaUtil() {}
/**
* Requires that the given message extend {@link com.google.protobuf.GeneratedMessageV3} or {@link
* GeneratedMessageLite}.
*/
public static void requireGeneratedMessage(Class<?> messageType) {
if (!GeneratedMessageLite.class.isAssignableFrom(messageType)
&& GENERATED_MESSAGE_CLASS != null
&& !GENERATED_MESSAGE_CLASS.isAssignableFrom(messageType)) {
throw new IllegalArgumentException(
"Message classes must extend GeneratedMessage or GeneratedMessageLite");
}
}
public static void writeDouble(int fieldNumber, double value, Writer writer) throws IOException {
if (Double.compare(value, 0.0) != 0) {
writer.writeDouble(fieldNumber, value);
}
}
public static void writeFloat(int fieldNumber, float value, Writer writer) throws IOException {
if (Float.compare(value, 0.0f) != 0) {
writer.writeFloat(fieldNumber, value);
}
}
public static void writeInt64(int fieldNumber, long value, Writer writer) throws IOException {
if (value != 0) {
writer.writeInt64(fieldNumber, value);
}
}
public static void writeUInt64(int fieldNumber, long value, Writer writer) throws IOException {
if (value != 0) {
writer.writeUInt64(fieldNumber, value);
}
}
public static void writeSInt64(int fieldNumber, long value, Writer writer) throws IOException {
if (value != 0) {
writer.writeSInt64(fieldNumber, value);
}
}
public static void writeFixed64(int fieldNumber, long value, Writer writer) throws IOException {
if (value != 0) {
writer.writeFixed64(fieldNumber, value);
}
}
public static void writeSFixed64(int fieldNumber, long value, Writer writer) throws IOException {
if (value != 0) {
writer.writeSFixed64(fieldNumber, value);
}
}
public static void writeInt32(int fieldNumber, int value, Writer writer) throws IOException {
if (value != 0) {
writer.writeInt32(fieldNumber, value);
}
}
public static void writeUInt32(int fieldNumber, int value, Writer writer) throws IOException {
if (value != 0) {
writer.writeUInt32(fieldNumber, value);
}
}
public static void writeSInt32(int fieldNumber, int value, Writer writer) throws IOException {
if (value != 0) {
writer.writeSInt32(fieldNumber, value);
}
}
public static void writeFixed32(int fieldNumber, int value, Writer writer) throws IOException {
if (value != 0) {
writer.writeFixed32(fieldNumber, value);
}
}
public static void writeSFixed32(int fieldNumber, int value, Writer writer) throws IOException {
if (value != 0) {
writer.writeSFixed32(fieldNumber, value);
}
}
public static void writeEnum(int fieldNumber, int value, Writer writer) throws IOException {
if (value != 0) {
writer.writeEnum(fieldNumber, value);
}
}
public static void writeBool(int fieldNumber, boolean value, Writer writer) throws IOException {
if (value) {
writer.writeBool(fieldNumber, true);
}
}
public static void writeString(int fieldNumber, Object value, Writer writer) throws IOException {
if (value instanceof String) {
writeStringInternal(fieldNumber, (String) value, writer);
} else {
writeBytes(fieldNumber, (ByteString) value, writer);
}
}
private static void writeStringInternal(int fieldNumber, String value, Writer writer)
throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeString(fieldNumber, value);
}
}
public static void writeBytes(int fieldNumber, ByteString value, Writer writer)
throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeBytes(fieldNumber, value);
}
}
public static void writeMessage(int fieldNumber, Object value, Writer writer) throws IOException {
if (value != null) {
writer.writeMessage(fieldNumber, value);
}
}
public static void writeDoubleList(
int fieldNumber, List<Double> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeDoubleList(fieldNumber, value, packed);
}
}
public static void writeFloatList(
int fieldNumber, List<Float> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeFloatList(fieldNumber, value, packed);
}
}
public static void writeInt64List(
int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeInt64List(fieldNumber, value, packed);
}
}
public static void writeUInt64List(
int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeUInt64List(fieldNumber, value, packed);
}
}
public static void writeSInt64List(
int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeSInt64List(fieldNumber, value, packed);
}
}
public static void writeFixed64List(
int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeFixed64List(fieldNumber, value, packed);
}
}
public static void writeSFixed64List(
int fieldNumber, List<Long> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeSFixed64List(fieldNumber, value, packed);
}
}
public static void writeInt32List(
int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeInt32List(fieldNumber, value, packed);
}
}
public static void writeUInt32List(
int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeUInt32List(fieldNumber, value, packed);
}
}
public static void writeSInt32List(
int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeSInt32List(fieldNumber, value, packed);
}
}
public static void writeFixed32List(
int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeFixed32List(fieldNumber, value, packed);
}
}
public static void writeSFixed32List(
int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeSFixed32List(fieldNumber, value, packed);
}
}
public static void writeEnumList(
int fieldNumber, List<Integer> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeEnumList(fieldNumber, value, packed);
}
}
public static void writeBoolList(
int fieldNumber, List<Boolean> value, Writer writer, boolean packed) throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeBoolList(fieldNumber, value, packed);
}
}
public static void writeStringList(int fieldNumber, List<String> value, Writer writer)
throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeStringList(fieldNumber, value);
}
}
public static void writeBytesList(int fieldNumber, List<ByteString> value, Writer writer)
throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeBytesList(fieldNumber, value);
}
}
public static void writeMessageList(int fieldNumber, List<?> value, Writer writer)
throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeMessageList(fieldNumber, value);
}
}
public static void writeMessageList(int fieldNumber, List<?> value, Writer writer, Schema schema)
throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeMessageList(fieldNumber, value, schema);
}
}
public static void writeLazyFieldList(int fieldNumber, List<?> value, Writer writer)
throws IOException {
if (value != null && !value.isEmpty()) {
for (Object item : value) {
((LazyFieldLite) item).writeTo(writer, fieldNumber);
}
}
}
public static void writeGroupList(int fieldNumber, List<?> value, Writer writer)
throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeGroupList(fieldNumber, value);
}
}
public static void writeGroupList(int fieldNumber, List<?> value, Writer writer, Schema schema)
throws IOException {
if (value != null && !value.isEmpty()) {
writer.writeGroupList(fieldNumber, value, schema);
}
}
static int computeSizeInt64ListNoTag(List<Long> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
if (list instanceof LongArrayList) {
final LongArrayList primitiveList = (LongArrayList) list;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeInt64SizeNoTag(primitiveList.getLong(i));
}
} else {
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeInt64SizeNoTag(list.get(i));
}
}
return size;
}
static int computeSizeInt64List(int fieldNumber, List<Long> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = computeSizeInt64ListNoTag(list);
if (packed) {
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(size);
} else {
return size + (list.size() * CodedOutputStream.computeTagSize(fieldNumber));
}
}
static int computeSizeUInt64ListNoTag(List<Long> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
if (list instanceof LongArrayList) {
final LongArrayList primitiveList = (LongArrayList) list;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeUInt64SizeNoTag(primitiveList.getLong(i));
}
} else {
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeUInt64SizeNoTag(list.get(i));
}
}
return size;
}
static int computeSizeUInt64List(int fieldNumber, List<Long> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = computeSizeUInt64ListNoTag(list);
if (packed) {
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(size);
} else {
return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
}
}
static int computeSizeSInt64ListNoTag(List<Long> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
if (list instanceof LongArrayList) {
final LongArrayList primitiveList = (LongArrayList) list;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeSInt64SizeNoTag(primitiveList.getLong(i));
}
} else {
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeSInt64SizeNoTag(list.get(i));
}
}
return size;
}
static int computeSizeSInt64List(int fieldNumber, List<Long> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = computeSizeSInt64ListNoTag(list);
if (packed) {
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(size);
} else {
return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
}
}
static int computeSizeEnumListNoTag(List<Integer> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
if (list instanceof IntArrayList) {
final IntArrayList primitiveList = (IntArrayList) list;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeEnumSizeNoTag(primitiveList.getInt(i));
}
} else {
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeEnumSizeNoTag(list.get(i));
}
}
return size;
}
static int computeSizeEnumList(int fieldNumber, List<Integer> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = computeSizeEnumListNoTag(list);
if (packed) {
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(size);
} else {
return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
}
}
static int computeSizeInt32ListNoTag(List<Integer> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
if (list instanceof IntArrayList) {
final IntArrayList primitiveList = (IntArrayList) list;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeInt32SizeNoTag(primitiveList.getInt(i));
}
} else {
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeInt32SizeNoTag(list.get(i));
}
}
return size;
}
static int computeSizeInt32List(int fieldNumber, List<Integer> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = computeSizeInt32ListNoTag(list);
if (packed) {
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(size);
} else {
return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
}
}
static int computeSizeUInt32ListNoTag(List<Integer> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
if (list instanceof IntArrayList) {
final IntArrayList primitiveList = (IntArrayList) list;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeUInt32SizeNoTag(primitiveList.getInt(i));
}
} else {
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeUInt32SizeNoTag(list.get(i));
}
}
return size;
}
static int computeSizeUInt32List(int fieldNumber, List<Integer> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = computeSizeUInt32ListNoTag(list);
if (packed) {
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(size);
} else {
return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
}
}
static int computeSizeSInt32ListNoTag(List<Integer> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
if (list instanceof IntArrayList) {
final IntArrayList primitiveList = (IntArrayList) list;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeSInt32SizeNoTag(primitiveList.getInt(i));
}
} else {
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeSInt32SizeNoTag(list.get(i));
}
}
return size;
}
static int computeSizeSInt32List(int fieldNumber, List<Integer> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = computeSizeSInt32ListNoTag(list);
if (packed) {
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(size);
} else {
return size + (length * CodedOutputStream.computeTagSize(fieldNumber));
}
}
static int computeSizeFixed32ListNoTag(List<?> list) {
return list.size() * WireFormat.FIXED32_SIZE;
}
static int computeSizeFixed32List(int fieldNumber, List<?> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
if (packed) {
int dataSize = length * WireFormat.FIXED32_SIZE;
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(dataSize);
} else {
return length * CodedOutputStream.computeFixed32Size(fieldNumber, 0);
}
}
static int computeSizeFixed64ListNoTag(List<?> list) {
return list.size() * WireFormat.FIXED64_SIZE;
}
static int computeSizeFixed64List(int fieldNumber, List<?> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
if (packed) {
final int dataSize = length * WireFormat.FIXED64_SIZE;
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(dataSize);
} else {
return length * CodedOutputStream.computeFixed64Size(fieldNumber, 0);
}
}
static int computeSizeBoolListNoTag(List<?> list) {
// bools are 1 byte varints
return list.size();
}
static int computeSizeBoolList(int fieldNumber, List<?> list, boolean packed) {
final int length = list.size();
if (length == 0) {
return 0;
}
if (packed) {
// bools are 1 byte varints
return CodedOutputStream.computeTagSize(fieldNumber)
+ CodedOutputStream.computeLengthDelimitedFieldSize(length);
} else {
return length * CodedOutputStream.computeBoolSize(fieldNumber, true);
}
}
static int computeSizeStringList(int fieldNumber, List<?> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = length * CodedOutputStream.computeTagSize(fieldNumber);
if (list instanceof LazyStringList) {
LazyStringList lazyList = ((LazyStringList) list);
for (int i = 0; i < length; i++) {
Object value = lazyList.getRaw(i);
if (value instanceof ByteString) {
size += CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
} else {
size += CodedOutputStream.computeStringSizeNoTag((String) value);
}
}
} else {
for (int i = 0; i < length; i++) {
Object value = list.get(i);
if (value instanceof ByteString) {
size += CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
} else {
size += CodedOutputStream.computeStringSizeNoTag((String) value);
}
}
}
return size;
}
static int computeSizeMessage(int fieldNumber, Object value, Schema schema) {
if (value instanceof LazyFieldLite) {
return CodedOutputStream.computeLazyFieldSize(fieldNumber, (LazyFieldLite) value);
} else {
return CodedOutputStream.computeMessageSize(fieldNumber, (MessageLite) value, schema);
}
}
static int computeSizeMessageList(int fieldNumber, List<?> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = length * CodedOutputStream.computeTagSize(fieldNumber);
for (int i = 0; i < length; i++) {
Object value = list.get(i);
if (value instanceof LazyFieldLite) {
size += CodedOutputStream.computeLazyFieldSizeNoTag((LazyFieldLite) value);
} else {
size += CodedOutputStream.computeMessageSizeNoTag((MessageLite) value);
}
}
return size;
}
static int computeSizeMessageList(int fieldNumber, List<?> list, Schema schema) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = length * CodedOutputStream.computeTagSize(fieldNumber);
for (int i = 0; i < length; i++) {
Object value = list.get(i);
if (value instanceof LazyFieldLite) {
size += CodedOutputStream.computeLazyFieldSizeNoTag((LazyFieldLite) value);
} else {
size += CodedOutputStream.computeMessageSizeNoTag((MessageLite) value, schema);
}
}
return size;
}
static int computeSizeByteStringList(int fieldNumber, List<ByteString> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = length * CodedOutputStream.computeTagSize(fieldNumber);
for (int i = 0; i < list.size(); i++) {
size += CodedOutputStream.computeBytesSizeNoTag(list.get(i));
}
return size;
}
static int computeSizeGroupList(int fieldNumber, List<MessageLite> list) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeGroupSize(fieldNumber, list.get(i));
}
return size;
}
static int computeSizeGroupList(int fieldNumber, List<MessageLite> list, Schema schema) {
final int length = list.size();
if (length == 0) {
return 0;
}
int size = 0;
for (int i = 0; i < length; i++) {
size += CodedOutputStream.computeGroupSize(fieldNumber, list.get(i), schema);
}
return size;
}
/**
* Determines whether to issue tableswitch or lookupswitch for the mergeFrom method.
*
* @see #shouldUseTableSwitch(int, int, int)
*/
public static boolean shouldUseTableSwitch(FieldInfo[] fields) {
// Determine whether to issue a tableswitch or a lookupswitch
// instruction.
if (fields.length == 0) {
return false;
}
int lo = fields[0].getFieldNumber();
int hi = fields[fields.length - 1].getFieldNumber();
return shouldUseTableSwitch(lo, hi, fields.length);
}
/**
* Determines whether to issue tableswitch or lookupswitch for the mergeFrom method. This is based
* on the <a href=
* "http://hg.openjdk.java.net/jdk8/jdk8/langtools/file/30db5e0aaf83/src/share/classes/com/sun/tools/javac/jvm/Gen.java#l1159">
* logic in the JDK</a>.
*
* @param lo the lowest fieldNumber contained within the message.
* @param hi the higest fieldNumber contained within the message.
* @param numFields the total number of fields in the message.
* @return {@code true} if tableswitch should be used, rather than lookupswitch.
*/
public static boolean shouldUseTableSwitch(int lo, int hi, int numFields) {
if (hi < DEFAULT_LOOK_UP_START_NUMBER) {
return true;
}
long tableSpaceCost = ((long) hi - lo + 1); // words
long tableTimeCost = 3; // comparisons
long lookupSpaceCost = 3 + 2 * (long) numFields;
long lookupTimeCost = 3 + (long) numFields;
return tableSpaceCost + 3 * tableTimeCost <= lookupSpaceCost + 3 * lookupTimeCost;
}
public static UnknownFieldSchema<?, ?> proto2UnknownFieldSetSchema() {
return PROTO2_UNKNOWN_FIELD_SET_SCHEMA;
}
public static UnknownFieldSchema<?, ?> proto3UnknownFieldSetSchema() {
return PROTO3_UNKNOWN_FIELD_SET_SCHEMA;
}
public static UnknownFieldSchema<?, ?> unknownFieldSetLiteSchema() {
return UNKNOWN_FIELD_SET_LITE_SCHEMA;
}
private static UnknownFieldSchema<?, ?> getUnknownFieldSetSchema(boolean proto3) {
try {
Class<?> clz = getUnknownFieldSetSchemaClass();
if (clz == null) {
return null;
}
return (UnknownFieldSchema) clz.getConstructor(boolean.class).newInstance(proto3);
} catch (Throwable t) {
return null;
}
}
private static Class<?> getGeneratedMessageClass() {
try {
return Class.forName("com.google.protobuf.GeneratedMessageV3");
} catch (Throwable e) {
return null;
}
}
private static Class<?> getUnknownFieldSetSchemaClass() {
try {
return Class.forName("com.google.protobuf.UnknownFieldSetSchema");
} catch (Throwable e) {
return null;
}
}
static Object getMapDefaultEntry(Class<?> clazz, String name) {
try {
Class<?> holder =
Class.forName(clazz.getName() + "$" + toCamelCase(name, true) + "DefaultEntryHolder");
Field[] fields = holder.getDeclaredFields();
if (fields.length != 1) {
throw new IllegalStateException(
"Unable to look up map field default entry holder class for "
+ name
+ " in "
+ clazz.getName());
}
return UnsafeUtil.getStaticObject(fields[0]);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
static String toCamelCase(String name, boolean capNext) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < name.length(); ++i) {
char c = name.charAt(i);
// Matches protoc field name function:
if ('a' <= c && c <= 'z') {
if (capNext) {
sb.append((char) (c + ('A' - 'a')));
} else {
sb.append(c);
}
capNext = false;
} else if ('A' <= c && c <= 'Z') {
if (i == 0 && !capNext) {
// Force first letter to lower-case unless explicitly told to capitalize it.
sb.append((char) (c - ('A' - 'a')));
} else {
sb.append(c);
}
capNext = false;
} else if ('0' <= c && c <= '9') {
sb.append(c);
capNext = true;
} else {
capNext = true;
}
}
return sb.toString();
}
/** Returns true if both are null or both are {@link Object#equals}. */
static boolean safeEquals(Object a, Object b) {
return a == b || (a != null && a.equals(b));
}
static <T> void mergeMap(MapFieldSchema mapFieldSchema, T message, T o, long offset) {
Object merged =
mapFieldSchema.mergeFrom(
UnsafeUtil.getObject(message, offset), UnsafeUtil.getObject(o, offset));
UnsafeUtil.putObject(message, offset, merged);
}
static <T, FT extends FieldDescriptorLite<FT>> void mergeExtensions(
ExtensionSchema<FT> schema, T message, T other) {
FieldSet<FT> otherExtensions = schema.getExtensions(other);
if (!otherExtensions.isEmpty()) {
FieldSet<FT> messageExtensions = schema.getMutableExtensions(message);
messageExtensions.mergeFrom(otherExtensions);
}
}
static <T, UT, UB> void mergeUnknownFields(
UnknownFieldSchema<UT, UB> schema, T message, T other) {
UT messageUnknowns = schema.getFromMessage(message);
UT otherUnknowns = schema.getFromMessage(other);
UT merged = schema.merge(messageUnknowns, otherUnknowns);
schema.setToMessage(message, merged);
}
/** Filters unrecognized enum values in a list. */
static <UT, UB> UB filterUnknownEnumList(
int number,
List<Integer> enumList,
EnumLiteMap<?> enumMap,
UB unknownFields,
UnknownFieldSchema<UT, UB> unknownFieldSchema) {
if (enumMap == null) {
return unknownFields;
}
// TODO(dweis): Specialize for IntArrayList to avoid boxing.
if (enumList instanceof RandomAccess) {
int writePos = 0;
int size = enumList.size();
for (int readPos = 0; readPos < size; ++readPos) {
int enumValue = enumList.get(readPos);
if (enumMap.findValueByNumber(enumValue) != null) {
if (readPos != writePos) {
enumList.set(writePos, enumValue);
}
++writePos;
} else {
unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
}
}
if (writePos != size) {
enumList.subList(writePos, size).clear();
}
} else {
for (Iterator<Integer> it = enumList.iterator(); it.hasNext(); ) {
int enumValue = it.next();
if (enumMap.findValueByNumber(enumValue) == null) {
unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
it.remove();
}
}
}
return unknownFields;
}
/** Filters unrecognized enum values in a list. */
static <UT, UB> UB filterUnknownEnumList(
int number,
List<Integer> enumList,
EnumVerifier enumVerifier,
UB unknownFields,
UnknownFieldSchema<UT, UB> unknownFieldSchema) {
if (enumVerifier == null) {
return unknownFields;
}
// TODO(dweis): Specialize for IntArrayList to avoid boxing.
if (enumList instanceof RandomAccess) {
int writePos = 0;
int size = enumList.size();
for (int readPos = 0; readPos < size; ++readPos) {
int enumValue = enumList.get(readPos);
if (enumVerifier.isInRange(enumValue)) {
if (readPos != writePos) {
enumList.set(writePos, enumValue);
}
++writePos;
} else {
unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
}
}
if (writePos != size) {
enumList.subList(writePos, size).clear();
}
} else {
for (Iterator<Integer> it = enumList.iterator(); it.hasNext(); ) {
int enumValue = it.next();
if (!enumVerifier.isInRange(enumValue)) {
unknownFields = storeUnknownEnum(number, enumValue, unknownFields, unknownFieldSchema);
it.remove();
}
}
}
return unknownFields;
}
/** Stores an unrecognized enum value as an unknown value. */
static <UT, UB> UB storeUnknownEnum(
int number, int enumValue, UB unknownFields, UnknownFieldSchema<UT, UB> unknownFieldSchema) {
if (unknownFields == null) {
unknownFields = unknownFieldSchema.newBuilder();
}
unknownFieldSchema.addVarint(unknownFields, number, enumValue);
return unknownFields;
}
}

View File

@ -136,6 +136,8 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
// The EntrySet is a stateless view of the Map. It's initialized the first
// time it is requested and reused henceforth.
private volatile EntrySet lazyEntrySet;
private Map<K, V> overflowEntriesDescending;
private volatile DescendingEntrySet lazyDescendingEntrySet;
/**
* @code arraySize Size of the array in which the lexicographically smallest mappings are stored.
@ -145,6 +147,7 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
this.maxArraySize = arraySize;
this.entryList = Collections.emptyList();
this.overflowEntries = Collections.emptyMap();
this.overflowEntriesDescending = Collections.emptyMap();
}
/** Make this map immutable from this point forward. */
@ -158,6 +161,10 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
overflowEntries.isEmpty()
? Collections.<K, V>emptyMap()
: Collections.unmodifiableMap(overflowEntries);
overflowEntriesDescending =
overflowEntriesDescending.isEmpty()
? Collections.<K, V>emptyMap()
: Collections.unmodifiableMap(overflowEntriesDescending);
isImmutable = true;
}
}
@ -189,6 +196,11 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
: overflowEntries.entrySet();
}
Iterable<Map.Entry<K, V>> getOverflowEntriesDescending() {
return overflowEntriesDescending.isEmpty()
? EmptySet.<Map.Entry<K, V>>iterable()
: overflowEntriesDescending.entrySet();
}
@Override
public int size() {
@ -344,6 +356,12 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
return lazyEntrySet;
}
Set<Map.Entry<K, V>> descendingEntrySet() {
if (lazyDescendingEntrySet == null) {
lazyDescendingEntrySet = new DescendingEntrySet();
}
return lazyDescendingEntrySet;
}
/** @throws UnsupportedOperationException if {@link #makeImmutable()} has has been called. */
private void checkMutable() {
@ -361,6 +379,7 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
checkMutable();
if (overflowEntries.isEmpty() && !(overflowEntries instanceof TreeMap)) {
overflowEntries = new TreeMap<K, V>();
overflowEntriesDescending = ((TreeMap<K, V>) overflowEntries).descendingMap();
}
return (SortedMap<K, V>) overflowEntries;
}
@ -501,6 +520,12 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
}
}
private class DescendingEntrySet extends EntrySet {
@Override
public Iterator<java.util.Map.Entry<K, V>> iterator() {
return new DescendingEntryIterator();
}
}
/**
* Iterator implementation that switches from the entry array to the overflow entries
@ -557,6 +582,46 @@ class SmallSortedMap<K extends Comparable<K>, V> extends AbstractMap<K, V> {
}
}
/**
* Reverse Iterator implementation that switches from the entry array to the overflow entries
* appropriately.
*/
private class DescendingEntryIterator implements Iterator<Map.Entry<K, V>> {
private int pos = entryList.size();
private Iterator<Map.Entry<K, V>> lazyOverflowIterator;
@Override
public boolean hasNext() {
return (pos > 0 && pos <= entryList.size()) || getOverflowIterator().hasNext();
}
@Override
public Map.Entry<K, V> next() {
if (getOverflowIterator().hasNext()) {
return getOverflowIterator().next();
}
return entryList.get(--pos);
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
/**
* It is important to create the overflow iterator only after the array entries have been
* iterated over because the overflow entry set changes when the client calls remove() on the
* array entries, which invalidates any existing iterators.
*/
private Iterator<Map.Entry<K, V>> getOverflowIterator() {
if (lazyOverflowIterator == null) {
lazyOverflowIterator = overflowEntriesDescending.entrySet().iterator();
}
return lazyOverflowIterator;
}
}
/**
* Helper class that holds immutable instances of an Iterable/Iterator that we return when the
* overflow entries is empty. This eliminates the creation of an Iterator object when there is

View File

@ -0,0 +1,167 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.Internal.checkNotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Information for the layout of a protobuf message class. This describes all of the fields
* contained within a message.
*/
@ExperimentalApi
final class StructuralMessageInfo implements MessageInfo {
private final ProtoSyntax syntax;
private final boolean messageSetWireFormat;
private final int[] checkInitialized;
private final FieldInfo[] fields;
private final MessageLite defaultInstance;
/**
* Constructor.
*
* @param checkInitialized fields to check in isInitialized().
* @param fields the set of fields for the message, in field number order.
*/
StructuralMessageInfo(
ProtoSyntax syntax,
boolean messageSetWireFormat,
int[] checkInitialized,
FieldInfo[] fields,
Object defaultInstance) {
this.syntax = syntax;
this.messageSetWireFormat = messageSetWireFormat;
this.checkInitialized = checkInitialized;
this.fields = fields;
this.defaultInstance = (MessageLite) checkNotNull(defaultInstance, "defaultInstance");
}
/** Gets the syntax for the message (e.g. PROTO2, PROTO3). */
@Override
public ProtoSyntax getSyntax() {
return syntax;
}
/** Indicates whether or not the message should be represented with message set wire format. */
@Override
public boolean isMessageSetWireFormat() {
return messageSetWireFormat;
}
/** An array of field numbers that need to be checked for isInitialized(). */
public int[] getCheckInitialized() {
return checkInitialized;
}
/**
* Gets the information for all fields within this message, sorted in ascending order by their
* field number.
*/
public FieldInfo[] getFields() {
return fields;
}
@Override
public MessageLite getDefaultInstance() {
return defaultInstance;
}
/** Helper method for creating a new builder for {@link MessageInfo}. */
public static Builder newBuilder() {
return new Builder();
}
/** Helper method for creating a new builder for {@link MessageInfo}. */
public static Builder newBuilder(int numFields) {
return new Builder(numFields);
}
/** A builder of {@link MessageInfo} instances. */
public static final class Builder {
private final List<FieldInfo> fields;
private ProtoSyntax syntax;
private boolean wasBuilt;
private boolean messageSetWireFormat;
private int[] checkInitialized = null;
private Object defaultInstance;
public Builder() {
fields = new ArrayList<FieldInfo>();
}
public Builder(int numFields) {
fields = new ArrayList<FieldInfo>(numFields);
}
public void withDefaultInstance(Object defaultInstance) {
this.defaultInstance = defaultInstance;
}
public void withSyntax(ProtoSyntax syntax) {
this.syntax = checkNotNull(syntax, "syntax");
}
public void withMessageSetWireFormat(boolean messageSetWireFormat) {
this.messageSetWireFormat = messageSetWireFormat;
}
public void withCheckInitialized(int[] checkInitialized) {
this.checkInitialized = checkInitialized;
}
public void withField(FieldInfo field) {
if (wasBuilt) {
throw new IllegalStateException("Builder can only build once");
}
fields.add(field);
}
public StructuralMessageInfo build() {
if (wasBuilt) {
throw new IllegalStateException("Builder can only build once");
}
if (syntax == null) {
throw new IllegalStateException("Must specify a proto syntax");
}
wasBuilt = true;
Collections.sort(fields);
return new StructuralMessageInfo(
syntax,
messageSetWireFormat,
checkInitialized,
fields.toArray(new FieldInfo[0]),
defaultInstance);
}
}
}

View File

@ -1247,6 +1247,18 @@ public final class TextFormat {
SingularOverwritePolicy.ALLOW_SINGULAR_OVERWRITES;
private TextFormatParseInfoTree.Builder parseInfoTreeBuilder = null;
/**
* Set whether this parser will allow unknown fields. By default, an exception is thrown if an
* unknown field is encountered. If this is set, the parser will only log a warning. Allow
* unknown fields will also allow unknown extensions.
*
* <p>Use of this parameter is discouraged which may hide some errors (e.g.
* spelling error on field name).
*/
public Builder setAllowUnknownFields(boolean allowUnknownFields) {
this.allowUnknownFields = allowUnknownFields;
return this;
}
/**
* Set whether this parser will allow unknown extensions. By default, an
@ -1448,7 +1460,8 @@ public final class TextFormat {
extension = target.findExtensionByName(extensionRegistry, name.toString());
if (extension == null) {
String message = (tokenizer.getPreviousLine() + 1)
String message =
(tokenizer.getPreviousLine() + 1)
+ ":"
+ (tokenizer.getPreviousColumn() + 1)
+ ":\t"
@ -1661,16 +1674,10 @@ public final class TextFormat {
if (tokenizer.atEnd()) {
throw tokenizer.parseException("Expected \"" + endToken + "\".");
}
mergeField(
tokenizer,
extensionRegistry,
subField,
parseTreeBuilder,
unknownFields);
mergeField(tokenizer, extensionRegistry, subField, parseTreeBuilder, unknownFields);
}
value = subField.finish();
} else {
switch (field.getType()) {
case INT32:
@ -1776,6 +1783,7 @@ public final class TextFormat {
}
}
/** Skips the next field including the field's name and value. */
private void skipField(Tokenizer tokenizer) throws ParseException {
if (tokenizer.tryConsume("[")) {

View File

@ -0,0 +1,133 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.io.IOException;
@ExperimentalApi
abstract class UnknownFieldSchema<T, B> {
/** Whether unknown fields should be dropped. */
abstract boolean shouldDiscardUnknownFields(Reader reader);
/** Adds a varint value to the unknown fields. */
abstract void addVarint(B fields, int number, long value);
/** Adds a fixed32 value to the unknown fields. */
abstract void addFixed32(B fields, int number, int value);
/** Adds a fixed64 value to the unknown fields. */
abstract void addFixed64(B fields, int number, long value);
/** Adds a length delimited value to the unknown fields. */
abstract void addLengthDelimited(B fields, int number, ByteString value);
/** Adds a group value to the unknown fields. */
abstract void addGroup(B fields, int number, T subFieldSet);
/** Create a new builder for unknown fields. */
abstract B newBuilder();
/** Returns an immutable instance of the field container. */
abstract T toImmutable(B fields);
/**
* Sets the unknown fields into the message. Caller must take care of the mutability of the
* fields.
*/
abstract void setToMessage(Object message, T fields);
/** Get the unknown fields from the message. */
abstract T getFromMessage(Object message);
/** Returns a builder for unknown fields in the message. */
abstract B getBuilderFromMessage(Object message);
/** Sets an unknown field builder into the message. */
abstract void setBuilderToMessage(Object message, B builder);
/** Marks unknown fields as immutable. */
abstract void makeImmutable(Object message);
/** Merges one field into the unknown fields. */
final boolean mergeOneFieldFrom(B unknownFields, Reader reader) throws IOException {
int tag = reader.getTag();
int fieldNumber = WireFormat.getTagFieldNumber(tag);
switch (WireFormat.getTagWireType(tag)) {
case WireFormat.WIRETYPE_VARINT:
addVarint(unknownFields, fieldNumber, reader.readInt64());
return true;
case WireFormat.WIRETYPE_FIXED32:
addFixed32(unknownFields, fieldNumber, reader.readFixed32());
return true;
case WireFormat.WIRETYPE_FIXED64:
addFixed64(unknownFields, fieldNumber, reader.readFixed64());
return true;
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
addLengthDelimited(unknownFields, fieldNumber, reader.readBytes());
return true;
case WireFormat.WIRETYPE_START_GROUP:
final B subFields = newBuilder();
int endGroupTag = WireFormat.makeTag(fieldNumber, WireFormat.WIRETYPE_END_GROUP);
mergeFrom(subFields, reader);
if (endGroupTag != reader.getTag()) {
throw InvalidProtocolBufferException.invalidEndTag();
}
addGroup(unknownFields, fieldNumber, toImmutable(subFields));
return true;
case WireFormat.WIRETYPE_END_GROUP:
return false;
default:
throw InvalidProtocolBufferException.invalidWireType();
}
}
final void mergeFrom(B unknownFields, Reader reader) throws IOException {
while (true) {
if (reader.getFieldNumber() == Reader.READ_DONE
|| !mergeOneFieldFrom(unknownFields, reader)) {
break;
}
}
}
abstract void writeTo(T unknownFields, Writer writer) throws IOException;
abstract void writeAsMessageSetTo(T unknownFields, Writer writer) throws IOException;
/** Merges {@code source} into {@code destination} and returns the merged instance. */
abstract T merge(T destination, T source);
/** Get the serialized size for message set serialization. */
abstract int getSerializedSizeAsMessageSet(T message);
abstract int getSerializedSize(T unknowns);
}

View File

@ -59,6 +59,7 @@ public final class UnknownFieldSet implements MessageLite {
private UnknownFieldSet() {
fields = null;
fieldsDescending = null;
}
/** Create a new {@link Builder}. */
@ -90,10 +91,14 @@ public final class UnknownFieldSet implements MessageLite {
*/
UnknownFieldSet(final Map<Integer, Field> fields, final Map<Integer, Field> fieldsDescending) {
this.fields = fields;
this.fieldsDescending = fieldsDescending;
}
private final Map<Integer, Field> fields;
/** A copy of {@link #fields} who's iterator order is reversed. */
private final Map<Integer, Field> fieldsDescending;
@Override
public boolean equals(final Object other) {
@ -212,6 +217,35 @@ public final class UnknownFieldSet implements MessageLite {
}
}
/** Serializes the set and writes it to {@code writer}. */
void writeTo(Writer writer) throws IOException {
if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
// Write fields in descending order.
for (Map.Entry<Integer, Field> entry : fieldsDescending.entrySet()) {
entry.getValue().writeTo(entry.getKey(), writer);
}
} else {
// Write fields in ascending order.
for (Map.Entry<Integer, Field> entry : fields.entrySet()) {
entry.getValue().writeTo(entry.getKey(), writer);
}
}
}
/** Serializes the set and writes it to {@code writer} using {@code MessageSet} wire format. */
void writeAsMessageSetTo(final Writer writer) throws IOException {
if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
// Write fields in descending order.
for (final Map.Entry<Integer, Field> entry : fieldsDescending.entrySet()) {
entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), writer);
}
} else {
// Write fields in ascending order.
for (final Map.Entry<Integer, Field> entry : fields.entrySet()) {
entry.getValue().writeAsMessageSetExtensionTo(entry.getKey(), writer);
}
}
}
/** Get the number of bytes required to encode this set using {@code MessageSet} wire format. */
public int getSerializedSizeAsMessageSet() {
@ -328,6 +362,8 @@ public final class UnknownFieldSet implements MessageLite {
result = getDefaultInstance();
} else {
Map<Integer, Field> descendingFields = null;
descendingFields =
Collections.unmodifiableMap(((TreeMap<Integer, Field>) fields).descendingMap());
result = new UnknownFieldSet(Collections.unmodifiableMap(fields), descendingFields);
}
fields = null;
@ -344,6 +380,8 @@ public final class UnknownFieldSet implements MessageLite {
public Builder clone() {
getFieldBuilder(0); // Force lastField to be built.
Map<Integer, Field> descendingFields = null;
descendingFields =
Collections.unmodifiableMap(((TreeMap<Integer, Field>) fields).descendingMap());
return UnknownFieldSet.newBuilder().mergeFrom(new UnknownFieldSet(fields, descendingFields));
}
@ -808,6 +846,47 @@ public final class UnknownFieldSet implements MessageLite {
}
}
/** Serializes the field, including field number, and writes it to {@code writer}. */
void writeTo(final int fieldNumber, final Writer writer) throws IOException {
writer.writeInt64List(fieldNumber, varint, false);
writer.writeFixed32List(fieldNumber, fixed32, false);
writer.writeFixed64List(fieldNumber, fixed64, false);
writer.writeBytesList(fieldNumber, lengthDelimited);
if (writer.fieldOrder() == Writer.FieldOrder.ASCENDING) {
for (int i = 0; i < group.size(); i++) {
writer.writeStartGroup(fieldNumber);
group.get(i).writeTo(writer);
writer.writeEndGroup(fieldNumber);
}
} else {
for (int i = group.size() - 1; i >= 0; i--) {
writer.writeEndGroup(fieldNumber);
group.get(i).writeTo(writer);
writer.writeStartGroup(fieldNumber);
}
}
}
/**
* Serializes the field, including field number, and writes it to {@code writer}, using {@code
* MessageSet} wire format.
*/
private void writeAsMessageSetExtensionTo(final int fieldNumber, final Writer writer)
throws IOException {
if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
// Write in descending field order.
ListIterator<ByteString> iter = lengthDelimited.listIterator(lengthDelimited.size());
while (iter.hasPrevious()) {
writer.writeMessageSetItem(fieldNumber, iter.previous());
}
} else {
// Write in ascending field order.
for (final ByteString value : lengthDelimited) {
writer.writeMessageSetItem(fieldNumber, value);
}
}
}
/**
* Get the number of bytes required to encode this field, including field number, using {@code

View File

@ -168,6 +168,72 @@ public final class UnknownFieldSetLite {
}
}
/** Serializes the set and writes it to {@code writer} using {@code MessageSet} wire format. */
void writeAsMessageSetTo(Writer writer) throws IOException {
if (writer.fieldOrder() == Writer.FieldOrder.DESCENDING) {
// Write fields in descending order.
for (int i = count - 1; i >= 0; i--) {
int fieldNumber = WireFormat.getTagFieldNumber(tags[i]);
writer.writeMessageSetItem(fieldNumber, objects[i]);
}
} else {
// Write fields in ascending order.
for (int i = 0; i < count; i++) {
int fieldNumber = WireFormat.getTagFieldNumber(tags[i]);
writer.writeMessageSetItem(fieldNumber, objects[i]);
}
}
}
/** Serializes the set and writes it to {@code writer}. */
public void writeTo(Writer writer) throws IOException {
if (count == 0) {
return;
}
// TODO: tags are not sorted, so there's no write order guarantees
if (writer.fieldOrder() == Writer.FieldOrder.ASCENDING) {
for (int i = 0; i < count; ++i) {
writeField(tags[i], objects[i], writer);
}
} else {
for (int i = count - 1; i >= 0; --i) {
writeField(tags[i], objects[i], writer);
}
}
}
private static void writeField(int tag, Object object, Writer writer) throws IOException {
int fieldNumber = WireFormat.getTagFieldNumber(tag);
switch (WireFormat.getTagWireType(tag)) {
case WireFormat.WIRETYPE_VARINT:
writer.writeInt64(fieldNumber, (Long) object);
break;
case WireFormat.WIRETYPE_FIXED32:
writer.writeFixed32(fieldNumber, (Integer) object);
break;
case WireFormat.WIRETYPE_FIXED64:
writer.writeFixed64(fieldNumber, (Long) object);
break;
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
writer.writeBytes(fieldNumber, (ByteString) object);
break;
case WireFormat.WIRETYPE_START_GROUP:
if (writer.fieldOrder() == Writer.FieldOrder.ASCENDING) {
writer.writeStartGroup(fieldNumber);
((UnknownFieldSetLite) object).writeTo(writer);
writer.writeEndGroup(fieldNumber);
} else {
writer.writeEndGroup(fieldNumber);
((UnknownFieldSetLite) object).writeTo(writer);
writer.writeStartGroup(fieldNumber);
}
break;
default:
// TODO(liujisi): Change writeTo to throw IOException?
throw new RuntimeException(InvalidProtocolBufferException.invalidWireType());
}
}
/**
* Get the number of bytes required to encode this field, including field number, using {@code

View File

@ -0,0 +1,140 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.io.IOException;
class UnknownFieldSetLiteSchema
extends UnknownFieldSchema<UnknownFieldSetLite, UnknownFieldSetLite> {
UnknownFieldSetLiteSchema() {}
@Override
boolean shouldDiscardUnknownFields(Reader reader) {
// We never drop unknown fields in lite.
return false;
}
@Override
UnknownFieldSetLite newBuilder() {
return UnknownFieldSetLite.newInstance();
}
@Override
void addVarint(UnknownFieldSetLite fields, int number, long value) {
fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_VARINT), value);
}
@Override
void addFixed32(UnknownFieldSetLite fields, int number, int value) {
fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_FIXED32), value);
}
@Override
void addFixed64(UnknownFieldSetLite fields, int number, long value) {
fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_FIXED64), value);
}
@Override
void addLengthDelimited(UnknownFieldSetLite fields, int number, ByteString value) {
fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED), value);
}
@Override
void addGroup(UnknownFieldSetLite fields, int number, UnknownFieldSetLite subFieldSet) {
fields.storeField(WireFormat.makeTag(number, WireFormat.WIRETYPE_START_GROUP), subFieldSet);
}
@Override
UnknownFieldSetLite toImmutable(UnknownFieldSetLite fields) {
fields.makeImmutable();
return fields;
}
@Override
void setToMessage(Object message, UnknownFieldSetLite fields) {
((GeneratedMessageLite<?, ?>) message).unknownFields = fields;
}
@Override
UnknownFieldSetLite getFromMessage(Object message) {
return ((GeneratedMessageLite<?, ?>) message).unknownFields;
}
@Override
UnknownFieldSetLite getBuilderFromMessage(Object message) {
UnknownFieldSetLite unknownFields = getFromMessage(message);
// When parsing into a lite message object, its UnknownFieldSet is either the default instance
// or mutable. It can't be in a state where it's immutable but not default instance.
if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = UnknownFieldSetLite.newInstance();
setToMessage(message, unknownFields);
}
return unknownFields;
}
@Override
void setBuilderToMessage(Object message, UnknownFieldSetLite fields) {
setToMessage(message, fields);
}
@Override
void makeImmutable(Object message) {
getFromMessage(message).makeImmutable();
}
@Override
void writeTo(UnknownFieldSetLite fields, Writer writer) throws IOException {
fields.writeTo(writer);
}
@Override
void writeAsMessageSetTo(UnknownFieldSetLite fields, Writer writer) throws IOException {
fields.writeAsMessageSetTo(writer);
}
@Override
UnknownFieldSetLite merge(UnknownFieldSetLite message, UnknownFieldSetLite other) {
return other.equals(UnknownFieldSetLite.getDefaultInstance())
? message
: UnknownFieldSetLite.mutableCopyOf(message, other);
}
@Override
int getSerializedSize(UnknownFieldSetLite unknowns) {
return unknowns.getSerializedSize();
}
@Override
int getSerializedSizeAsMessageSet(UnknownFieldSetLite unknowns) {
return unknowns.getSerializedSizeAsMessageSet();
}
}

View File

@ -0,0 +1,132 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.io.IOException;
class UnknownFieldSetSchema extends UnknownFieldSchema<UnknownFieldSet, UnknownFieldSet.Builder> {
private final boolean proto3;
public UnknownFieldSetSchema(boolean proto3) {
this.proto3 = proto3;
}
@Override
boolean shouldDiscardUnknownFields(Reader reader) {
return reader.shouldDiscardUnknownFields();
}
@Override
UnknownFieldSet.Builder newBuilder() {
return UnknownFieldSet.newBuilder();
}
@Override
void addVarint(UnknownFieldSet.Builder fields, int number, long value) {
fields.mergeField(number, UnknownFieldSet.Field.newBuilder().addVarint(value).build());
}
@Override
void addFixed32(UnknownFieldSet.Builder fields, int number, int value) {
fields.mergeField(number, UnknownFieldSet.Field.newBuilder().addFixed32(value).build());
}
@Override
void addFixed64(UnknownFieldSet.Builder fields, int number, long value) {
fields.mergeField(number, UnknownFieldSet.Field.newBuilder().addFixed64(value).build());
}
@Override
void addLengthDelimited(UnknownFieldSet.Builder fields, int number, ByteString value) {
fields.mergeField(number, UnknownFieldSet.Field.newBuilder().addLengthDelimited(value).build());
}
@Override
void addGroup(UnknownFieldSet.Builder fields, int number, UnknownFieldSet subFieldSet) {
fields.mergeField(number, UnknownFieldSet.Field.newBuilder().addGroup(subFieldSet).build());
}
@Override
UnknownFieldSet toImmutable(UnknownFieldSet.Builder fields) {
return fields.build();
}
@Override
void writeTo(UnknownFieldSet message, Writer writer) throws IOException {
message.writeTo(writer);
}
@Override
void writeAsMessageSetTo(UnknownFieldSet message, Writer writer) throws IOException {
message.writeAsMessageSetTo(writer);
}
@Override
UnknownFieldSet getFromMessage(Object message) {
return ((GeneratedMessageV3) message).unknownFields;
}
@Override
void setToMessage(Object message, UnknownFieldSet fields) {
((GeneratedMessageV3) message).unknownFields = fields;
}
@Override
UnknownFieldSet.Builder getBuilderFromMessage(Object message) {
return ((GeneratedMessageV3) message).unknownFields.toBuilder();
}
@Override
void setBuilderToMessage(Object message, UnknownFieldSet.Builder builder) {
((GeneratedMessageV3) message).unknownFields = builder.build();
}
@Override
void makeImmutable(Object message) {
// Already immutable.
}
@Override
UnknownFieldSet merge(UnknownFieldSet message, UnknownFieldSet other) {
return message.toBuilder().mergeFrom(other).build();
}
@Override
int getSerializedSize(UnknownFieldSet message) {
return message.getSerializedSize();
}
@Override
int getSerializedSizeAsMessageSet(UnknownFieldSet unknowns) {
return unknowns.getSerializedSizeAsMessageSet();
}
}

View File

@ -794,7 +794,7 @@ final class Utf8 {
// if it occurs.
try {
// Designed to take advantage of
// https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
// https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
for (char c; inIx < inLength && (c = in.charAt(inIx)) < 0x80; ++inIx) {
out.put(outIx + inIx, (byte) c);
}
@ -1041,7 +1041,7 @@ final class Utf8 {
int i = 0;
int limit = offset + length;
// Designed to take advantage of
// https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
// https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
for (char c; i < utf16Length && i + j < limit && (c = in.charAt(i)) < 0x80; i++) {
out[j + i] = (byte) c;
}
@ -1527,7 +1527,7 @@ final class Utf8 {
}
// Designed to take advantage of
// https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
// https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
int inIx = 0;
for (char c; inIx < inLimit && (c = in.charAt(inIx)) < 0x80; ++inIx) {
UnsafeUtil.putByte(out, outIx++, (byte) c);
@ -1589,7 +1589,7 @@ final class Utf8 {
}
// Designed to take advantage of
// https://wikis.oracle.com/display/HotSpotInternals/RangeCheckElimination
// https://wiki.openjdk.java.net/display/HotSpotInternals/RangeCheckElimination
int inIx = 0;
for (char c; inIx < inLimit && (c = in.charAt(inIx)) < 0x80; ++inIx) {
UnsafeUtil.putByte(outIx++, (byte) c);

View File

@ -0,0 +1,219 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/** A writer that performs serialization of protobuf message fields. */
@ExperimentalApi
interface Writer {
/** The order in which the fields are written by a {@link Writer}. */
enum FieldOrder {
/** Fields are written in ascending order by field number. */
ASCENDING,
/** Fields are written in descending order by field number. */
DESCENDING
}
/** Indicates the order in which the fields are written by this {@link Writer}. */
FieldOrder fieldOrder();
/** Writes a field of type {@link FieldType#SFIXED32}. */
void writeSFixed32(int fieldNumber, int value) throws IOException;
/** Writes a field of type {@link FieldType#INT64}. */
void writeInt64(int fieldNumber, long value) throws IOException;
/** Writes a field of type {@link FieldType#SFIXED64}. */
void writeSFixed64(int fieldNumber, long value) throws IOException;
/** Writes a field of type {@link FieldType#FLOAT}. */
void writeFloat(int fieldNumber, float value) throws IOException;
/** Writes a field of type {@link FieldType#DOUBLE}. */
void writeDouble(int fieldNumber, double value) throws IOException;
/** Writes a field of type {@link FieldType#ENUM}. */
void writeEnum(int fieldNumber, int value) throws IOException;
/** Writes a field of type {@link FieldType#UINT64}. */
void writeUInt64(int fieldNumber, long value) throws IOException;
/** Writes a field of type {@link FieldType#INT32}. */
void writeInt32(int fieldNumber, int value) throws IOException;
/** Writes a field of type {@link FieldType#FIXED64}. */
void writeFixed64(int fieldNumber, long value) throws IOException;
/** Writes a field of type {@link FieldType#FIXED32}. */
void writeFixed32(int fieldNumber, int value) throws IOException;
/** Writes a field of type {@link FieldType#BOOL}. */
void writeBool(int fieldNumber, boolean value) throws IOException;
/** Writes a field of type {@link FieldType#STRING}. */
void writeString(int fieldNumber, String value) throws IOException;
/** Writes a field of type {@link FieldType#BYTES}. */
void writeBytes(int fieldNumber, ByteString value) throws IOException;
/** Writes a field of type {@link FieldType#UINT32}. */
void writeUInt32(int fieldNumber, int value) throws IOException;
/** Writes a field of type {@link FieldType#SINT32}. */
void writeSInt32(int fieldNumber, int value) throws IOException;
/** Writes a field of type {@link FieldType#SINT64}. */
void writeSInt64(int fieldNumber, long value) throws IOException;
/** Writes a field of type {@link FieldType#MESSAGE}. */
void writeMessage(int fieldNumber, Object value) throws IOException;
/** Writes a field of type {@link FieldType#MESSAGE}. */
void writeMessage(int fieldNumber, Object value, Schema schema) throws IOException;
/**
* Writes a field of type {@link FieldType#GROUP}.
*
* @deprecated groups fields are deprecated.
*/
@Deprecated
void writeGroup(int fieldNumber, Object value) throws IOException;
/**
* Writes a field of type {@link FieldType#GROUP}.
*
* @deprecated groups fields are deprecated.
*/
@Deprecated
void writeGroup(int fieldNumber, Object value, Schema schema) throws IOException;
/**
* Writes a single start group tag.
*
* @deprecated groups fields are deprecated.
*/
@Deprecated
void writeStartGroup(int fieldNumber) throws IOException;
/**
* Writes a single end group tag.
*
* @deprecated groups fields are deprecated.
*/
@Deprecated
void writeEndGroup(int fieldNumber) throws IOException;
/** Writes a list field of type {@link FieldType#INT32}. */
void writeInt32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#FIXED32}. */
void writeFixed32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#INT64}. */
void writeInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#UINT64}. */
void writeUInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#FIXED64}. */
void writeFixed64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#FLOAT}. */
void writeFloatList(int fieldNumber, List<Float> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#DOUBLE}. */
void writeDoubleList(int fieldNumber, List<Double> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#ENUM}. */
void writeEnumList(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#BOOL}. */
void writeBoolList(int fieldNumber, List<Boolean> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#STRING}. */
void writeStringList(int fieldNumber, List<String> value) throws IOException;
/** Writes a list field of type {@link FieldType#BYTES}. */
void writeBytesList(int fieldNumber, List<ByteString> value) throws IOException;
/** Writes a list field of type {@link FieldType#UINT32}. */
void writeUInt32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#SFIXED32}. */
void writeSFixed32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#SFIXED64}. */
void writeSFixed64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#SINT32}. */
void writeSInt32List(int fieldNumber, List<Integer> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#SINT64}. */
void writeSInt64List(int fieldNumber, List<Long> value, boolean packed) throws IOException;
/** Writes a list field of type {@link FieldType#MESSAGE}. */
void writeMessageList(int fieldNumber, List<?> value) throws IOException;
/** Writes a list field of type {@link FieldType#MESSAGE}. */
void writeMessageList(int fieldNumber, List<?> value, Schema schema) throws IOException;
/**
* Writes a list field of type {@link FieldType#GROUP}.
*
* @deprecated groups fields are deprecated.
*/
@Deprecated
void writeGroupList(int fieldNumber, List<?> value) throws IOException;
/**
* Writes a list field of type {@link FieldType#GROUP}.
*
* @deprecated groups fields are deprecated.
*/
@Deprecated
void writeGroupList(int fieldNumber, List<?> value, Schema schema) throws IOException;
/**
* Writes a message field in {@code MessageSet} wire-format.
*
* @param value A message instance or an opaque {@link ByteString} for an unknown field.
*/
void writeMessageSetItem(int fieldNumber, Object value) throws IOException;
/** Writes a map field. */
<K, V> void writeMap(int fieldNumber, MapEntryLite.Metadata<K, V> metadata, Map<K, V> map)
throws IOException;
}

View File

@ -0,0 +1,199 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import com.google.protobuf.testing.Proto2TestingLite.Proto2EmptyLite;
import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite;
import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite.TestEnum;
import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLiteWithMaps;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
/** Base class for tests using {@link Proto2MessageLite}. */
public abstract class AbstractProto2LiteSchemaTest extends AbstractSchemaTest<Proto2MessageLite> {
@Override
protected Proto2MessageLiteFactory messageFactory() {
return new Proto2MessageLiteFactory(10, 20, 2, 2);
}
@Test
public void mergeOptionalMessageFields() throws Exception {
Proto2MessageLite message1 =
newBuilder()
.setFieldMessage10(newBuilder().setFieldInt643(123).clearFieldInt325().build())
.build();
Proto2MessageLite message2 =
newBuilder()
.setFieldMessage10(newBuilder().clearFieldInt643().setFieldInt325(456).build())
.build();
Proto2MessageLite message3 =
newBuilder()
.setFieldMessage10(newBuilder().setFieldInt643(789).clearFieldInt325().build())
.build();
ByteArrayOutputStream output = new ByteArrayOutputStream();
message1.writeTo(output);
message2.writeTo(output);
message3.writeTo(output);
byte[] data = output.toByteArray();
Proto2MessageLite merged =
ExperimentalSerializationUtil.fromByteArray(data, Proto2MessageLite.class);
assertEquals(789, merged.getFieldMessage10().getFieldInt643());
assertEquals(456, merged.getFieldMessage10().getFieldInt325());
}
@Test
public void oneofFieldsShouldRoundtrip() throws IOException {
roundtrip("Field 53", newBuilder().setFieldDouble53(100).build());
roundtrip("Field 54", newBuilder().setFieldFloat54(100).build());
roundtrip("Field 55", newBuilder().setFieldInt6455(100).build());
roundtrip("Field 56", newBuilder().setFieldUint6456(100L).build());
roundtrip("Field 57", newBuilder().setFieldInt3257(100).build());
roundtrip("Field 58", newBuilder().setFieldFixed6458(100).build());
roundtrip("Field 59", newBuilder().setFieldFixed3259(100).build());
roundtrip("Field 60", newBuilder().setFieldBool60(true).build());
roundtrip("Field 61", newBuilder().setFieldString61(data().getString()).build());
roundtrip(
"Field 62", newBuilder().setFieldMessage62(newBuilder().setFieldDouble1(100)).build());
roundtrip("Field 63", newBuilder().setFieldBytes63(data().getBytes()).build());
roundtrip("Field 64", newBuilder().setFieldUint3264(100).build());
roundtrip("Field 65", newBuilder().setFieldSfixed3265(100).build());
roundtrip("Field 66", newBuilder().setFieldSfixed6466(100).build());
roundtrip("Field 67", newBuilder().setFieldSint3267(100).build());
roundtrip("Field 68", newBuilder().setFieldSint6468(100).build());
roundtrip(
"Field 69",
newBuilder()
.setFieldGroup69(
Proto2MessageLite.FieldGroup69.newBuilder().setFieldInt3270(data().getInt()))
.build());
}
private Proto2MessageLite.Builder newBuilder() {
return messageFactory().newMessage().toBuilder();
}
@Override
protected List<Proto2MessageLite> newMessagesMissingRequiredFields() {
return messageFactory().newMessagesMissingRequiredFields();
}
@Test
public void mapsShouldRoundtrip() throws IOException {
roundtrip(
"Proto2MessageLiteWithMaps",
new Proto2MessageLiteFactory(2, 10, 2, 2).newMessageWithMaps(),
Protobuf.getInstance().schemaFor(Proto2MessageLiteWithMaps.class));
}
@Test
public void unknownFieldsUnrecognized() throws Exception {
Proto2MessageLite expectedMessage = messageFactory().newMessage();
byte[] serializedBytes = expectedMessage.toByteArray();
Proto2EmptyLite empty =
ExperimentalSerializationUtil.fromByteArray(serializedBytes, Proto2EmptyLite.class);
// Merge serialized bytes into an empty message, then reserialize and merge it to a new
// Proto2Message. Make sure the two messages equal.
byte[] roundtripBytes = ExperimentalSerializationUtil.toByteArray(empty);
Proto2MessageLite roundtripMessage =
ExperimentalSerializationUtil.fromByteArray(roundtripBytes, Proto2MessageLite.class);
assertEquals(expectedMessage, roundtripMessage);
}
@Test
public void unknownEnum() throws IOException {
// Use unknown fields to hold invalid enum values.
UnknownFieldSetLite unknowns = UnknownFieldSetLite.newInstance();
final int outOfRange = 1000;
assertNull(TestEnum.forNumber(outOfRange));
unknowns.storeField(
WireFormat.makeTag(
Proto2MessageLite.FIELD_ENUM_13_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) outOfRange);
unknowns.storeField(
WireFormat.makeTag(
Proto2MessageLite.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) TestEnum.ONE_VALUE);
unknowns.storeField(
WireFormat.makeTag(
Proto2MessageLite.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) outOfRange);
unknowns.storeField(
WireFormat.makeTag(
Proto2MessageLite.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) TestEnum.TWO_VALUE);
{
// Construct a packed enum list.
int packedSize =
CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE)
+ CodedOutputStream.computeUInt32SizeNoTag(outOfRange)
+ CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE);
ByteString.CodedBuilder packedBuilder = ByteString.newCodedBuilder(packedSize);
CodedOutputStream packedOut = packedBuilder.getCodedOutput();
packedOut.writeEnumNoTag(TestEnum.ONE_VALUE);
packedOut.writeEnumNoTag(outOfRange);
packedOut.writeEnumNoTag(TestEnum.TWO_VALUE);
unknowns.storeField(
WireFormat.makeTag(
Proto2MessageLite.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER,
WireFormat.WIRETYPE_LENGTH_DELIMITED),
packedBuilder.build());
}
int size = unknowns.getSerializedSize();
byte[] output = new byte[size];
CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
unknowns.writeTo(codedOutput);
codedOutput.flush();
Proto2MessageLite parsed =
ExperimentalSerializationUtil.fromByteArray(output, Proto2MessageLite.class);
assertFalse("out-of-range singular enum should not be in message", parsed.hasFieldEnum13());
assertEquals(
"out-of-range repeated enum should not be in message", 2, parsed.getFieldEnumList30Count());
assertEquals(TestEnum.ONE, parsed.getFieldEnumList30(0));
assertEquals(TestEnum.TWO, parsed.getFieldEnumList30(1));
assertEquals(
"out-of-range packed repeated enum should not be in message",
2,
parsed.getFieldEnumListPacked44Count());
assertEquals(TestEnum.ONE, parsed.getFieldEnumListPacked44(0));
assertEquals(TestEnum.TWO, parsed.getFieldEnumListPacked44(1));
}
}

View File

@ -0,0 +1,224 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import com.google.protobuf.testing.Proto2Testing.Proto2Empty;
import com.google.protobuf.testing.Proto2Testing.Proto2Message;
import com.google.protobuf.testing.Proto2Testing.Proto2Message.TestEnum;
import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithMaps;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
/** Base class for tests using {@link Proto2Message}. */
public abstract class AbstractProto2SchemaTest extends AbstractSchemaTest<Proto2Message> {
@Override
protected Proto2MessageFactory messageFactory() {
return new Proto2MessageFactory(10, 20, 2, 2);
}
@Test
public void mergeOptionalMessageFields() throws Exception {
Proto2Message message1 =
newBuilder()
.setFieldMessage10(newBuilder().setFieldInt643(123).clearFieldInt325().build())
.build();
Proto2Message message2 =
newBuilder()
.setFieldMessage10(newBuilder().clearFieldInt643().setFieldInt325(456).build())
.build();
Proto2Message message3 =
newBuilder()
.setFieldMessage10(newBuilder().setFieldInt643(789).clearFieldInt325().build())
.build();
ByteArrayOutputStream output = new ByteArrayOutputStream();
message1.writeTo(output);
message2.writeTo(output);
message3.writeTo(output);
byte[] data = output.toByteArray();
Proto2Message merged = ExperimentalSerializationUtil.fromByteArray(data, Proto2Message.class);
assertEquals(789, merged.getFieldMessage10().getFieldInt643());
assertEquals(456, merged.getFieldMessage10().getFieldInt325());
}
@Test
public void oneofFieldsShouldRoundtrip() throws IOException {
roundtrip("Field 53", newBuilder().setFieldDouble53(100).build());
roundtrip("Field 54", newBuilder().setFieldFloat54(100).build());
roundtrip("Field 55", newBuilder().setFieldInt6455(100).build());
roundtrip("Field 56", newBuilder().setFieldUint6456(100L).build());
roundtrip("Field 57", newBuilder().setFieldInt3257(100).build());
roundtrip("Field 58", newBuilder().setFieldFixed6458(100).build());
roundtrip("Field 59", newBuilder().setFieldFixed3259(100).build());
roundtrip("Field 60", newBuilder().setFieldBool60(true).build());
roundtrip("Field 61", newBuilder().setFieldString61(data().getString()).build());
roundtrip(
"Field 62", newBuilder().setFieldMessage62(newBuilder().setFieldDouble1(100)).build());
roundtrip("Field 63", newBuilder().setFieldBytes63(data().getBytes()).build());
roundtrip("Field 64", newBuilder().setFieldUint3264(100).build());
roundtrip("Field 65", newBuilder().setFieldSfixed3265(100).build());
roundtrip("Field 66", newBuilder().setFieldSfixed6466(100).build());
roundtrip("Field 67", newBuilder().setFieldSint3267(100).build());
roundtrip("Field 68", newBuilder().setFieldSint6468(100).build());
roundtrip(
"Field 69",
newBuilder()
.setFieldGroup69(
Proto2Message.FieldGroup69.newBuilder().setFieldInt3270(data().getInt()))
.build());
}
private Proto2Message.Builder newBuilder() {
return messageFactory().newMessage().toBuilder();
}
@Test
public void mapsShouldRoundtrip() throws IOException {
roundtrip(
"Proto2MessageWithMaps",
new Proto2MessageFactory(2, 10, 2, 2).newMessageWithMaps(),
Protobuf.getInstance().schemaFor(Proto2MessageWithMaps.class));
}
@Test
public void unknownFieldsUnrecognized() throws Exception {
Proto2Message expectedMessage = messageFactory().newMessage();
byte[] serializedBytes = expectedMessage.toByteArray();
Proto2Empty empty =
ExperimentalSerializationUtil.fromByteArray(serializedBytes, Proto2Empty.class);
// Merge serialized bytes into an empty message, then reserialize and merge it to a new
// Proto2Message. Make sure the two messages equal.
byte[] roundtripBytes = ExperimentalSerializationUtil.toByteArray(empty);
assertEquals(serializedBytes.length, roundtripBytes.length);
Proto2Message roundtripMessage =
ExperimentalSerializationUtil.fromByteArray(roundtripBytes, Proto2Message.class);
assertEquals(expectedMessage, roundtripMessage);
}
@Test
public void unknownEnum() throws IOException {
// Use unknown fields to hold invalid enum values.
UnknownFieldSetLite unknowns = UnknownFieldSetLite.newInstance();
final int outOfRange = 1000;
assertNull(TestEnum.forNumber(outOfRange));
unknowns.storeField(
WireFormat.makeTag(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) outOfRange);
unknowns.storeField(
WireFormat.makeTag(
Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) TestEnum.ONE_VALUE);
unknowns.storeField(
WireFormat.makeTag(
Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) outOfRange);
unknowns.storeField(
WireFormat.makeTag(
Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) TestEnum.TWO_VALUE);
{
// Construct a packed enum list.
int packedSize =
CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE)
+ CodedOutputStream.computeUInt32SizeNoTag(outOfRange)
+ CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE);
ByteString.CodedBuilder packedBuilder = ByteString.newCodedBuilder(packedSize);
CodedOutputStream packedOut = packedBuilder.getCodedOutput();
packedOut.writeEnumNoTag(TestEnum.ONE_VALUE);
packedOut.writeEnumNoTag(outOfRange);
packedOut.writeEnumNoTag(TestEnum.TWO_VALUE);
unknowns.storeField(
WireFormat.makeTag(
Proto2Message.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER,
WireFormat.WIRETYPE_LENGTH_DELIMITED),
packedBuilder.build());
}
int size = unknowns.getSerializedSize();
byte[] output = new byte[size];
CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
unknowns.writeTo(codedOutput);
codedOutput.flush();
Proto2Message parsed = ExperimentalSerializationUtil.fromByteArray(output, Proto2Message.class);
assertFalse("out-of-range singular enum should not be in message", parsed.hasFieldEnum13());
{
List<Long> singularEnum =
parsed
.getUnknownFields()
.getField(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER)
.getVarintList();
assertEquals(1, singularEnum.size());
assertEquals((Long) (long) outOfRange, singularEnum.get(0));
}
{
List<Long> repeatedEnum =
parsed
.getUnknownFields()
.getField(Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER)
.getVarintList();
assertEquals(1, repeatedEnum.size());
assertEquals((Long) (long) outOfRange, repeatedEnum.get(0));
}
{
List<Long> packedRepeatedEnum =
parsed
.getUnknownFields()
.getField(Proto2Message.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER)
.getVarintList();
assertEquals(1, packedRepeatedEnum.size());
assertEquals((Long) (long) outOfRange, packedRepeatedEnum.get(0));
}
assertEquals(
"out-of-range repeated enum should not be in message", 2, parsed.getFieldEnumList30Count());
assertEquals(TestEnum.ONE, parsed.getFieldEnumList30(0));
assertEquals(TestEnum.TWO, parsed.getFieldEnumList30(1));
assertEquals(
"out-of-range packed repeated enum should not be in message",
2,
parsed.getFieldEnumListPacked44Count());
assertEquals(TestEnum.ONE, parsed.getFieldEnumListPacked44(0));
assertEquals(TestEnum.TWO, parsed.getFieldEnumListPacked44(1));
}
@Override
protected List<Proto2Message> newMessagesMissingRequiredFields() {
return messageFactory().newMessagesMissingRequiredFields();
}
}

View File

@ -0,0 +1,143 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import com.google.protobuf.testing.Proto3TestingLite.Proto3EmptyLite;
import com.google.protobuf.testing.Proto3TestingLite.Proto3MessageLite;
import com.google.protobuf.testing.Proto3TestingLite.Proto3MessageLiteWithMaps;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
/** Base class for tests using {@link Proto3MessageLite}. */
public abstract class AbstractProto3LiteSchemaTest extends AbstractSchemaTest<Proto3MessageLite> {
@Override
protected Proto3MessageLiteFactory messageFactory() {
return new Proto3MessageLiteFactory(10, 20, 2, 2);
}
@Override
protected List<ByteBuffer> serializedBytesWithInvalidUtf8() throws IOException {
List<ByteBuffer> invalidBytes = new ArrayList<>();
byte[] invalid = new byte[] {(byte) 0x80};
{
ByteBuffer buffer = ByteBuffer.allocate(100);
CodedOutputStream codedOutput = CodedOutputStream.newInstance(buffer);
codedOutput.writeByteArray(Proto3MessageLite.FIELD_STRING_9_FIELD_NUMBER, invalid);
codedOutput.flush();
buffer.flip();
invalidBytes.add(buffer);
}
{
ByteBuffer buffer = ByteBuffer.allocate(100);
CodedOutputStream codedOutput = CodedOutputStream.newInstance(buffer);
codedOutput.writeByteArray(Proto3MessageLite.FIELD_STRING_LIST_26_FIELD_NUMBER, invalid);
codedOutput.flush();
buffer.flip();
invalidBytes.add(buffer);
}
return invalidBytes;
}
@Test
public void mergeOptionalMessageFields() throws Exception {
Proto3MessageLite message1 =
newBuilder()
.setFieldMessage10(newBuilder().setFieldInt643(123).clearFieldInt325().build())
.build();
Proto3MessageLite message2 =
newBuilder()
.setFieldMessage10(newBuilder().clearFieldInt643().setFieldInt325(456).build())
.build();
Proto3MessageLite message3 =
newBuilder()
.setFieldMessage10(newBuilder().setFieldInt643(789).clearFieldInt325().build())
.build();
ByteArrayOutputStream output = new ByteArrayOutputStream();
message1.writeTo(output);
message2.writeTo(output);
message3.writeTo(output);
byte[] data = output.toByteArray();
Proto3MessageLite merged =
ExperimentalSerializationUtil.fromByteArray(data, Proto3MessageLite.class);
assertEquals(789, merged.getFieldMessage10().getFieldInt643());
assertEquals(456, merged.getFieldMessage10().getFieldInt325());
}
@Test
public void oneofFieldsShouldRoundtrip() throws IOException {
roundtrip("Field 53", newBuilder().setFieldDouble53(100).build());
roundtrip("Field 54", newBuilder().setFieldFloat54(100).build());
roundtrip("Field 55", newBuilder().setFieldInt6455(100).build());
roundtrip("Field 56", newBuilder().setFieldUint6456(100L).build());
roundtrip("Field 57", newBuilder().setFieldInt3257(100).build());
roundtrip("Field 58", newBuilder().setFieldFixed6458(100).build());
roundtrip("Field 59", newBuilder().setFieldFixed3259(100).build());
roundtrip("Field 60", newBuilder().setFieldBool60(true).build());
roundtrip("Field 61", newBuilder().setFieldString61(data().getString()).build());
roundtrip(
"Field 62", newBuilder().setFieldMessage62(newBuilder().setFieldDouble1(100)).build());
roundtrip("Field 63", newBuilder().setFieldBytes63(data().getBytes()).build());
roundtrip("Field 64", newBuilder().setFieldUint3264(100).build());
roundtrip("Field 65", newBuilder().setFieldSfixed3265(100).build());
roundtrip("Field 66", newBuilder().setFieldSfixed6466(100).build());
roundtrip("Field 67", newBuilder().setFieldSint3267(100).build());
roundtrip("Field 68", newBuilder().setFieldSint6468(100).build());
}
@Test
public void retainUnknownFields() {
// Unknown fields are retained in lite runtime.
Proto3MessageLite expectedMessage = messageFactory().newMessage();
Proto3EmptyLite empty =
ExperimentalSerializationUtil.fromByteArray(
expectedMessage.toByteArray(), Proto3EmptyLite.class);
assertEquals(expectedMessage.getSerializedSize(), empty.getSerializedSize());
}
@Test
public void mapsShouldRoundtrip() throws IOException {
roundtrip(
"Proto3MessageLiteWithMaps",
new Proto3MessageLiteFactory(2, 10, 2, 2).newMessageWithMaps(),
Protobuf.getInstance().schemaFor(Proto3MessageLiteWithMaps.class));
}
private static Proto3MessageLite.Builder newBuilder() {
return Proto3MessageLite.newBuilder();
}
}

View File

@ -0,0 +1,151 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import com.google.protobuf.testing.Proto3Testing.Proto3Empty;
import com.google.protobuf.testing.Proto3Testing.Proto3Message;
import com.google.protobuf.testing.Proto3Testing.Proto3MessageWithMaps;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
/** Base class for tests using {@link Proto3Message}. */
public abstract class AbstractProto3SchemaTest extends AbstractSchemaTest<Proto3Message> {
@Override
protected Proto3MessageFactory messageFactory() {
return new Proto3MessageFactory(10, 20, 2, 2);
}
@Override
protected List<ByteBuffer> serializedBytesWithInvalidUtf8() throws IOException {
List<ByteBuffer> invalidBytes = new ArrayList<>();
byte[] invalid = new byte[] {(byte) 0x80};
{
ByteBuffer buffer = ByteBuffer.allocate(100);
CodedOutputStream codedOutput = CodedOutputStream.newInstance(buffer);
codedOutput.writeByteArray(Proto3Message.FIELD_STRING_9_FIELD_NUMBER, invalid);
codedOutput.flush();
buffer.flip();
invalidBytes.add(buffer);
}
{
ByteBuffer buffer = ByteBuffer.allocate(100);
CodedOutputStream codedOutput = CodedOutputStream.newInstance(buffer);
codedOutput.writeByteArray(Proto3Message.FIELD_STRING_LIST_26_FIELD_NUMBER, invalid);
codedOutput.flush();
buffer.flip();
invalidBytes.add(buffer);
}
return invalidBytes;
}
@Test
public void mergeOptionalMessageFields() throws Exception {
Proto3Message message1 =
newBuilder()
.setFieldMessage10(newBuilder().setFieldInt643(123).clearFieldInt325().build())
.build();
Proto3Message message2 =
newBuilder()
.setFieldMessage10(newBuilder().clearFieldInt643().setFieldInt325(456).build())
.build();
Proto3Message message3 =
newBuilder()
.setFieldMessage10(newBuilder().setFieldInt643(789).clearFieldInt325().build())
.build();
ByteArrayOutputStream output = new ByteArrayOutputStream();
message1.writeTo(output);
message2.writeTo(output);
message3.writeTo(output);
byte[] data = output.toByteArray();
Proto3Message merged = ExperimentalSerializationUtil.fromByteArray(data, Proto3Message.class);
assertEquals(789, merged.getFieldMessage10().getFieldInt643());
assertEquals(456, merged.getFieldMessage10().getFieldInt325());
}
@Test
public void oneofFieldsShouldRoundtrip() throws IOException {
roundtrip("Field 53", newBuilder().setFieldDouble53(100).build());
roundtrip("Field 54", newBuilder().setFieldFloat54(100).build());
roundtrip("Field 55", newBuilder().setFieldInt6455(100).build());
roundtrip("Field 56", newBuilder().setFieldUint6456(100L).build());
roundtrip("Field 57", newBuilder().setFieldInt3257(100).build());
roundtrip("Field 58", newBuilder().setFieldFixed6458(100).build());
roundtrip("Field 59", newBuilder().setFieldFixed3259(100).build());
roundtrip("Field 60", newBuilder().setFieldBool60(true).build());
roundtrip("Field 61", newBuilder().setFieldString61(data().getString()).build());
roundtrip(
"Field 62", newBuilder().setFieldMessage62(newBuilder().setFieldDouble1(100)).build());
roundtrip("Field 63", newBuilder().setFieldBytes63(data().getBytes()).build());
roundtrip("Field 64", newBuilder().setFieldUint3264(100).build());
roundtrip("Field 65", newBuilder().setFieldSfixed3265(100).build());
roundtrip("Field 66", newBuilder().setFieldSfixed6466(100).build());
roundtrip("Field 67", newBuilder().setFieldSint3267(100).build());
roundtrip("Field 68", newBuilder().setFieldSint6468(100).build());
}
@Test
public void preserveUnknownFields() {
Proto3Message expectedMessage = messageFactory().newMessage();
Proto3Empty empty =
ExperimentalSerializationUtil.fromByteArray(
expectedMessage.toByteArray(), Proto3Empty.class);
assertEquals(expectedMessage.getSerializedSize(), empty.getSerializedSize());
assertEquals(expectedMessage.toByteString(), empty.toByteString());
}
@Test
public void preserveUnknownFieldsProto2() {
// Make sure we will be able to preserve valid proto2 wireformat, including those that are not
// supported in proto3, e.g. groups.
byte[] payload = new Proto2MessageFactory(10, 20, 2, 2).newMessage().toByteArray();
Proto3Empty empty = ExperimentalSerializationUtil.fromByteArray(payload, Proto3Empty.class);
assertEquals(payload.length, empty.getSerializedSize());
}
@Test
public void mapsShouldRoundtrip() throws IOException {
roundtrip(
"Proto3MessageWithMaps",
new Proto3MessageFactory(2, 10, 2, 2).newMessageWithMaps(),
Protobuf.getInstance().schemaFor(Proto3MessageWithMaps.class));
}
private static Proto3Message.Builder newBuilder() {
return Proto3Message.newBuilder();
}
}

View File

@ -0,0 +1,157 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
public abstract class AbstractSchemaTest<T extends MessageLite> {
private Schema<T> schema;
@Before
public void setup() {
schema = schema();
registerSchemas();
}
// Subclass should override this method if it needs to register more than one schemas.
protected void registerSchemas() {
// Register this schema with the runtime to support processing of nested messages.
Protobuf.getInstance().registerSchemaOverride(schema.newInstance().getClass(), schema);
}
protected abstract Schema<T> schema();
protected abstract ExperimentalMessageFactory<? extends T> messageFactory();
@SuppressWarnings("unused")
protected List<ByteBuffer> serializedBytesWithInvalidUtf8() throws IOException {
return Collections.emptyList();
}
@Test
public void randomMessageShouldRoundtrip() throws IOException {
roundtrip("", messageFactory().newMessage());
}
@Test
public void invalidUtf8StringParsing() throws IOException {
for (ByteBuffer invalidUtf8Bytes : serializedBytesWithInvalidUtf8()) {
Reader reader = BinaryReader.newInstance(invalidUtf8Bytes, /* bufferIsImmutable= */ true);
T newMsg = schema.newInstance();
try {
schema.mergeFrom(newMsg, reader, ExtensionRegistryLite.getEmptyRegistry());
fail("should throw invalid ");
} catch (InvalidProtocolBufferException expected) {
}
}
}
@Test
public void mergeFromByteArrayFastPathMayThrowIndexOutOfBoundsException() throws IOException {
if (!Android.isOnAndroidDevice()) {
// Skip this test if not on Android.
return;
}
byte[] data = messageFactory().newMessage().toByteArray();
int exceptionCount = 0;
for (int i = 0; i <= data.length; i++) {
byte[] truncatedData = Arrays.copyOf(data, i);
try {
T message = schema.newInstance();
// Test that this method throws the expected exceptions.
schema.mergeFrom(message, truncatedData, 0, i, new ArrayDecoders.Registers());
} catch (InvalidProtocolBufferException e) {
// Ignore expected exceptions.
} catch (IndexOutOfBoundsException e) {
exceptionCount += 1;
}
}
assertNotEquals(0, exceptionCount);
}
protected static final <M extends MessageLite> void roundtrip(
String failureMessage, M msg, Schema<M> schema) throws IOException {
byte[] serializedBytes = ExperimentalSerializationUtil.toByteArray(msg, schema);
assertEquals(failureMessage, msg.getSerializedSize(), serializedBytes.length);
// Now read it back in and verify it matches the original.
if (Android.isOnAndroidDevice()) {
// Test the fast path on Android.
M newMsg = schema.newInstance();
schema.mergeFrom(
newMsg, serializedBytes, 0, serializedBytes.length, new ArrayDecoders.Registers());
schema.makeImmutable(newMsg);
assertEquals(failureMessage, msg, newMsg);
}
M newMsg = schema.newInstance();
Reader reader = BinaryReader.newInstance(ByteBuffer.wrap(serializedBytes), true);
schema.mergeFrom(newMsg, reader, ExtensionRegistryLite.getEmptyRegistry());
schema.makeImmutable(newMsg);
assertEquals(failureMessage, msg, newMsg);
}
protected final void roundtrip(String failureMessage, T msg) throws IOException {
roundtrip(failureMessage, msg, schema);
}
protected final ExperimentalTestDataProvider data() {
return messageFactory().dataProvider();
}
protected List<T> newMessagesMissingRequiredFields() {
return Collections.emptyList();
}
@SuppressWarnings("unchecked")
@Test
public void testRequiredFields() throws Exception {
for (T msg : newMessagesMissingRequiredFields()) {
if (schema.isInitialized(msg)) {
assertEquals("", msg.toString());
msg = (T) msg.toBuilder().build();
}
assertFalse(schema.isInitialized(msg));
}
}
}

View File

@ -0,0 +1,236 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.ArrayDecoders.Registers;
import java.io.IOException;
import junit.framework.TestCase;
public class ArrayDecodersTest extends TestCase {
private static final int TAG = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
private static final ByteString NEGATIVE_SIZE_0 = generateNegativeLength(0);
private static final ByteString NEGATIVE_SIZE_1 = generateNegativeLength(1);
private Registers registers;
@Override
public void setUp() {
registers = new Registers();
registers.int1 = TAG;
}
public void testException_decodeString() {
try {
ArrayDecoders.decodeString(NEGATIVE_SIZE_0.toByteArray(), 0, registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeStringRequireUtf8() {
try {
ArrayDecoders.decodeStringRequireUtf8(NEGATIVE_SIZE_0.toByteArray(), 0, registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeBytes() {
try {
ArrayDecoders.decodeBytes(NEGATIVE_SIZE_0.toByteArray(), 0, registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeStringList_first() {
try {
ArrayDecoders.decodeStringList(
TAG,
NEGATIVE_SIZE_0.toByteArray(),
0,
NEGATIVE_SIZE_0.size(),
new ProtobufArrayList<Object>(),
registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeStringList_second() {
try {
ArrayDecoders.decodeStringList(
TAG,
NEGATIVE_SIZE_1.toByteArray(),
0,
NEGATIVE_SIZE_1.size(),
new ProtobufArrayList<Object>(),
registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeStringListRequireUtf8_first() {
try {
ArrayDecoders.decodeStringListRequireUtf8(
TAG,
NEGATIVE_SIZE_0.toByteArray(),
0,
NEGATIVE_SIZE_0.size(),
new ProtobufArrayList<Object>(),
registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeStringListRequireUtf8_second() {
try {
ArrayDecoders.decodeStringListRequireUtf8(
TAG,
NEGATIVE_SIZE_1.toByteArray(),
0,
NEGATIVE_SIZE_1.size(),
new ProtobufArrayList<Object>(),
registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeBytesList_first() {
try {
ArrayDecoders.decodeBytesList(
TAG,
NEGATIVE_SIZE_0.toByteArray(),
0,
NEGATIVE_SIZE_0.size(),
new ProtobufArrayList<Object>(),
registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeBytesList_second() {
try {
ArrayDecoders.decodeBytesList(
TAG,
NEGATIVE_SIZE_1.toByteArray(),
0,
NEGATIVE_SIZE_1.size(),
new ProtobufArrayList<Object>(),
registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeUnknownField() {
try {
ArrayDecoders.decodeUnknownField(
TAG,
NEGATIVE_SIZE_0.toByteArray(),
0,
NEGATIVE_SIZE_0.size(),
UnknownFieldSetLite.newInstance(),
registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
public void testException_decodeHugeField() {
byte[] badBytes =
new byte[] {
(byte) 0x80, (byte) 0xFF, (byte) 0xFF, (byte) 0xEF, 0x73, 0x74, 0x69, 0x6E, 0x67
};
try {
ArrayDecoders.decodeUnknownField(
TAG, badBytes, 0, badBytes.length, UnknownFieldSetLite.newInstance(), registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
try {
ArrayDecoders.decodeBytes(badBytes, 0, registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
byte[] badBytesList =
new byte[] {
0x01,
0x77,
0x0A,
(byte) 0x80,
(byte) 0xFF,
(byte) 0xFF,
(byte) 0xEF,
0x73,
0x74,
0x69,
0x6E,
0x67
};
try {
ArrayDecoders.decodeBytesList(
TAG, badBytesList, 0, badBytes.length, new ProtobufArrayList<>(), registers);
fail();
} catch (InvalidProtocolBufferException expected) {
}
}
private static ByteString generateNegativeLength(int count) {
try {
ByteString.Output byteStringOutput = ByteString.newOutput();
CodedOutputStream codedOutput = CodedOutputStream.newInstance(byteStringOutput);
// Write out count - 1 valid 0 length fields; we only write out tags after the field since
// ArrayDecoders expects the first tag to already have been parsed.
for (int i = 0; i < count; i++) {
codedOutput.writeInt32NoTag(0);
codedOutput.writeInt32NoTag(TAG);
}
// Write out a negative length
codedOutput.writeInt32NoTag(-1);
codedOutput.flush();
return byteStringOutput.toByteString();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,90 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import com.google.protobuf.testing.Proto2Testing.Proto2Message;
import com.google.protobuf.testing.Proto3Testing.Proto3Message;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public final class BinaryProtocolTest {
@Before
public void setup() {
TestSchemas.registerGenericProto2Schemas();
Protobuf.getInstance()
.registerSchemaOverride(Proto3Message.class, TestSchemas.genericProto3Schema);
}
@Test
public void proto3Roundtrip() throws Exception {
Proto3Message expected = new Proto3MessageFactory(5, 10, 2, 2).newMessage();
byte[] expectedBytes = expected.toByteArray();
// Deserialize with BinaryReader and verify that the message matches the original.
Proto3Message result =
ExperimentalSerializationUtil.fromByteArray(expectedBytes, Proto3Message.class);
assertEquals(expected, result);
// Now write it back out using BinaryWriter and verify the output length.
byte[] actualBytes = ExperimentalSerializationUtil.toByteArray(result);
Assert.assertEquals(expectedBytes.length, actualBytes.length);
// Read back in the bytes and verify that it matches the original message.
Proto3Message actual = Proto3Message.parseFrom(actualBytes);
assertEquals(expected, actual);
}
@Test
public void proto2Roundtrip() throws Exception {
Proto2Message expected = new Proto2MessageFactory(5, 10, 2, 2).newMessage();
byte[] expectedBytes = expected.toByteArray();
// Deserialize with BinaryReader and verify that the message matches the original.
Proto2Message result =
ExperimentalSerializationUtil.fromByteArray(expectedBytes, Proto2Message.class);
assertEquals(expected, result);
// Now write it back out using BinaryWriter and verify the output length.
byte[] actualBytes = ExperimentalSerializationUtil.toByteArray(result);
Assert.assertEquals(expectedBytes.length, actualBytes.length);
// Read back in the bytes and verify that it matches the original message.
Proto2Message actual = Proto2Message.parseFrom(actualBytes);
assertEquals(expected, actual);
}
}

View File

@ -0,0 +1,65 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import protobuf_unittest.UnittestProto.TestPackedTypes;
import proto3_unittest.UnittestProto3;
import protobuf_unittest.TestCachedFieldSizeMessage;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public final class CachedFieldSizeTest {
// Regression test for b/74087933
@Test
public void testCachedFieldSize() throws Exception {
TestCachedFieldSizeMessage.Builder builder = TestCachedFieldSizeMessage.newBuilder();
builder.setProto2Child(TestUtil.getPackedSet());
builder.setProto3Child(
UnittestProto3.TestPackedTypes.parseFrom(TestUtil.getPackedSet().toByteArray()));
TestCachedFieldSizeMessage message = builder.build();
// Serialize once to cache all field sizes. This will use the experimental runtime because
// the proto has optimize_for = CODE_SIZE.
message.toByteArray();
// Serialize individual submessages. This will use the generated implementation. If the
// experimental runtime hasn't set the correct cached size, this will throw an exception.
byte[] data2 = message.getProto2Child().toByteArray();
byte[] data3 = message.getProto3Child().toByteArray();
// Make sure the serialized data is correct.
assertEquals(message.getProto2Child(), TestPackedTypes.parseFrom(data2));
assertEquals(message.getProto3Child(), UnittestProto3.TestPackedTypes.parseFrom(data3));
}
}

View File

@ -0,0 +1,110 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import com.google.protobuf.testing.Proto2Testing.Proto2Message;
import com.google.protobuf.testing.Proto3Testing.Proto3Message;
import java.io.IOException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public final class CodedAdapterTest {
@Before
public void setup() {
TestSchemas.registerGenericProto2Schemas();
Protobuf.getInstance()
.registerSchemaOverride(Proto3Message.class, TestSchemas.genericProto3Schema);
}
@Test
public void proto3Roundtrip() throws Exception {
Proto3Message expected = new Proto3MessageFactory(5, 10, 2, 2).newMessage();
byte[] expectedBytes = expected.toByteArray();
// Deserialize with BinaryReader and verify that the message matches the original.
Proto3Message result = fromByteArray(expectedBytes, Proto3Message.class);
assertEquals(expected, result);
// Now write it back out using BinaryWriter and verify the output length.
byte[] actualBytes = toByteArray(result, expectedBytes.length);
// Read back in the bytes and verify that it matches the original message.
Proto3Message actual = Proto3Message.parseFrom(actualBytes);
assertEquals(expected, actual);
}
@Test
public void proto2Roundtrip() throws Exception {
Proto2Message expected = new Proto2MessageFactory(5, 10, 2, 2).newMessage();
byte[] expectedBytes = expected.toByteArray();
// Deserialize with BinaryReader and verify that the message matches the original.
Proto2Message result = fromByteArray(expectedBytes, Proto2Message.class);
assertEquals(expected, result);
// Now write it back out using BinaryWriter and verify the output length.
byte[] actualBytes = toByteArray(result, expectedBytes.length);
// Read back in the bytes and verify that it matches the original message.
Proto2Message actual = Proto2Message.parseFrom(actualBytes);
assertEquals(expected, actual);
}
public static <T> byte[] toByteArray(T msg, int size) throws Exception {
Schema<T> schema = Protobuf.getInstance().schemaFor(msg);
byte[] out = new byte[size];
CodedOutputStreamWriter writer =
CodedOutputStreamWriter.forCodedOutput(CodedOutputStream.newInstance(out));
schema.writeTo(msg, writer);
assertEquals(out.length, writer.getTotalBytesWritten());
return out;
}
public static <T> T fromByteArray(byte[] data, Class<T> messageType) {
Schema<T> schema = Protobuf.getInstance().schemaFor(messageType);
try {
T msg = schema.newInstance();
schema.mergeFrom(
msg,
CodedInputStreamReader.forCodedInput(CodedInputStream.newInstance(data)),
ExtensionRegistryLite.EMPTY_REGISTRY_LITE);
return msg;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -44,6 +44,7 @@ import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
/**
@ -1195,4 +1196,59 @@ public class CodedInputStreamTest extends TestCase {
// Expected
}
}
public void testMaliciousInputStream() throws Exception {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CodedOutputStream codedOutputStream = CodedOutputStream.newInstance(outputStream);
codedOutputStream.writeByteArrayNoTag(new byte[] { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5 });
codedOutputStream.flush();
final List<byte[]> maliciousCapture = new ArrayList<>();
InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()) {
@Override
public synchronized int read(byte[] b, int off, int len) {
maliciousCapture.add(b);
return super.read(b, off, len);
}
};
// test ByteString
CodedInputStream codedInputStream = CodedInputStream.newInstance(inputStream, 1);
ByteString byteString = codedInputStream.readBytes();
assertEquals(0x0, byteString.byteAt(0));
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x0, byteString.byteAt(0));
// test ByteBuffer
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);
ByteBuffer byteBuffer = codedInputStream.readByteBuffer();
assertEquals(0x0, byteBuffer.get(0));
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x0, byteBuffer.get(0));
// test byte[]
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);
byte[] byteArray = codedInputStream.readByteArray();
assertEquals(0x0, byteArray[0]);
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x9, byteArray[0]); // MODIFICATION! Should we fix?
// test rawBytes
inputStream.reset();
maliciousCapture.clear();
codedInputStream = CodedInputStream.newInstance(inputStream, 1);
int length = codedInputStream.readRawVarint32();
byteArray = codedInputStream.readRawBytes(length);
assertEquals(0x0, byteArray[0]);
maliciousCapture.get(1)[0] = 0x9;
assertEquals(0x9, byteArray[0]); // MODIFICATION! Should we fix?
}
}

View File

@ -30,6 +30,8 @@
package com.google.protobuf;
import protobuf_unittest.NestedExtension;
import protobuf_unittest.NonNestedExtension;
import com.google.protobuf.DescriptorProtos.DescriptorProto;
import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProto;
@ -779,4 +781,23 @@ public class DescriptorsTest extends TestCase {
assertEquals("FIELDNAME5", d.getFields().get(4).getJsonName());
assertEquals("@type", d.getFields().get(5).getJsonName());
}
public void testExtensionRenamesKeywords() {
assertTrue(NonNestedExtension.if_ instanceof GeneratedMessage.GeneratedExtension);
assertTrue(
NestedExtension.MyNestedExtension.default_
instanceof GeneratedMessage.GeneratedExtension);
NonNestedExtension.MessageToBeExtended msg =
NonNestedExtension.MessageToBeExtended.newBuilder()
.setExtension(NonNestedExtension.if_, "!fi")
.build();
assertEquals("!fi", msg.getExtension(NonNestedExtension.if_));
msg =
NonNestedExtension.MessageToBeExtended.newBuilder()
.setExtension(NestedExtension.MyNestedExtension.default_, 8)
.build();
assertEquals(8, msg.getExtension(NestedExtension.MyNestedExtension.default_).intValue());
}
}

View File

@ -0,0 +1,40 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
/** Interface for a test factory for messages. */
public interface ExperimentalMessageFactory<T extends MessageLite> {
/** Creates a new random message instance. */
T newMessage();
/** Gets the underlying data provider. */
ExperimentalTestDataProvider dataProvider();
}

View File

@ -0,0 +1,113 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Queue;
/** Utilities for serialization. */
public class ExperimentalSerializationUtil {
/**
* Serializes the given message to a byte array using {@link com.google.protobuf.BinaryWriter}.
*/
public static <T> byte[] toByteArray(T msg) throws IOException {
return toByteArray(msg, Protobuf.getInstance().schemaFor(msg));
}
/**
* Serializes the given message to a byte array using {@link com.google.protobuf.BinaryWriter}
* with a customized Schema.
*/
public static <T> byte[] toByteArray(T msg, Schema<T> schema) throws IOException {
BinaryWriter writer = BinaryWriter.newHeapInstance(BufferAllocator.unpooled());
schema.writeTo(msg, writer);
byte[] out = new byte[writer.getTotalBytesWritten()];
int outPos = 0;
Queue<AllocatedBuffer> buffers = writer.complete();
while (true) {
AllocatedBuffer buffer = buffers.poll();
if (buffer == null) {
break;
}
int length = buffer.limit() - buffer.position();
System.arraycopy(
buffer.array(), buffer.arrayOffset() + buffer.position(), out, outPos, length);
outPos += length;
}
if (out.length != outPos) {
throw new IllegalArgumentException("Failed to serialize test message");
}
return out;
}
/** Deserializes a message from the given byte array. */
public static <T> T fromByteArray(byte[] data, Class<T> messageType) {
if (Android.isOnAndroidDevice()) {
return fromByteArrayFastPath(data, messageType);
} else {
return fromByteArray(data, messageType, ExtensionRegistryLite.getEmptyRegistry());
}
}
/**
* Deserializes a message from the given byte array using {@link com.google.protobuf.BinaryReader}
* with an extension registry and a customized Schema.
*/
public static <T> T fromByteArray(
byte[] data, Class<T> messageType, ExtensionRegistryLite extensionRegistry) {
try {
Schema<T> schema = Protobuf.getInstance().schemaFor(messageType);
T msg = schema.newInstance();
schema.mergeFrom(
msg, BinaryReader.newInstance(ByteBuffer.wrap(data), true), extensionRegistry);
schema.makeImmutable(msg);
return msg;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/** Deserializes a lite message from the given byte array using fast path. */
private static <T> T fromByteArrayFastPath(byte[] data, Class<T> messageType) {
try {
Schema<T> schema = Protobuf.getInstance().schemaFor(messageType);
T msg = schema.newInstance();
schema.mergeFrom(msg, data, 0, data.length, new ArrayDecoders.Registers());
schema.makeImmutable(msg);
return msg;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,189 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import java.util.Random;
/** Utility class that provides data primitives for filling out protobuf messages. */
public final class ExperimentalTestDataProvider {
private static final Random RANDOM = new Random(100);
private final Varint32Provider varint32s = new Varint32Provider();
private final Varint64Provider varint64s = new Varint64Provider();
private final int stringLength;
public ExperimentalTestDataProvider(int stringLength) {
this.stringLength = stringLength;
}
public double getDouble() {
double value = 0.0;
while (Double.compare(0.0, value) == 0) {
value = RANDOM.nextDouble();
}
return value;
}
public float getFloat() {
float value = 0.0f;
while (Float.compare(0.0f, value) == 0) {
value = RANDOM.nextFloat();
}
return value;
}
public long getLong() {
return varint64s.getLong();
}
public int getInt() {
return varint32s.getInt();
}
public boolean getBool() {
return true;
}
public int getEnum() {
return Math.abs(getInt()) % 3;
}
public String getString() {
StringBuilder builder = new StringBuilder(stringLength);
for (int i = 0; i < stringLength; ++i) {
builder.append((char) (RANDOM.nextInt('z' - 'a') + 'a'));
}
return builder.toString();
}
public ByteString getBytes() {
return ByteString.copyFromUtf8(getString());
}
/**
* Iterator over integer values. Uses a simple distribution over 32-bit varints (generally
* favoring smaller values).
*/
private static final class Varint32Provider {
private static final int[][] VALUES = {
new int[] {1, 50, 100, 127}, // 1 byte values
new int[] {128, 500, 10000, 16383}, // 2 bytes values
new int[] {16384, 50000, 1000000, 2097151}, // 3 bytes values
new int[] {2097152, 10000000, 200000000, 268435455}, // 4 bytes values
new int[] {268435456, 0x30000000, 0x7FFFFFFF, 0xFFFFFFFF} // 5 bytes values
};
/** Number of samples that should be taken from each value array. */
private static final int[] NUM_SAMPLES = {3, 2, 1, 1, 2};
/**
* The index into the {@link #VALUES} array that identifies the list of samples currently being
* iterated over.
*/
private int listIndex;
/** The index of the next sample within a list. */
private int sampleIndex;
/** The number of successive samples that have been taken from the current list. */
private int samplesTaken;
public int getInt() {
if (samplesTaken++ > NUM_SAMPLES[listIndex]) {
// Done taking samples from this list. Go to the next one.
listIndex = (listIndex + 1) % VALUES.length;
sampleIndex = 0;
samplesTaken = 0;
}
int value = VALUES[listIndex][sampleIndex];
// All lists are exactly 4 long (i.e. power of 2), so we can optimize the mod operation
// with masking.
sampleIndex = (sampleIndex + 1) & 3;
return value;
}
}
/**
* Iterator over integer values. Uses a simple distribution over 64-bit varints (generally
* favoring smaller values).
*/
private static final class Varint64Provider {
private static final long[][] VALUES = {
new long[] {1, 50, 100, 127},
new long[] {128, 500, 10000, 16383},
new long[] {16384, 50000, 1000000, 2097151},
new long[] {2097152, 10000000, 200000000, 268435455},
new long[] {268435456, 0x30000000, 0x7FFFFFFF, 34359738367L},
new long[] {34359738368L, 2000000000000L, 4000000000000L, 4398046511103L},
new long[] {4398046511104L, 200000000000000L, 500000000000000L, 562949953421311L},
new long[] {0x4000000000000L, 0x5000000000000L, 0x6000000000000L, 0x0FFFFFFFFFFFFFFL},
new long[] {0x100000000000000L, 0x3FFFFFFFFFFFFFFFL, 0x5FFFFFFFFFFFFFFL, 0x7FFFFFFFFFFFFFFFL},
new long[] {
0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL, 0xFFFFFFFFFFFFFFFFL
}
};
/** Number of samples that should be taken from each value array. */
private static final int[] NUM_SAMPLES = {4, 2, 2, 1, 1, 1, 1, 2, 2, 4};
/**
* The index into the {@link #VALUES} array that identifies the list of samples currently being
* iterated over.
*/
private int listIndex;
/** The index of the next sample within a list. */
private int sampleIndex;
/** The number of successive samples that have been taken from the current list. */
private int samplesTaken;
public long getLong() {
if (samplesTaken++ > NUM_SAMPLES[listIndex]) {
// Done taking samples from this list. Go to the next one.
listIndex = (listIndex + 1) % VALUES.length;
sampleIndex = 0;
samplesTaken = 0;
}
long value = VALUES[listIndex][sampleIndex];
// All lists are exactly 4 long (i.e. power of 2), so we can optimize the mod operation
// with masking.
sampleIndex = (sampleIndex + 1) & 3;
return value;
}
}
}

View File

@ -30,8 +30,6 @@
package com.google.protobuf;
import protobuf_unittest.NestedExtension;
import protobuf_unittest.NestedExtensionLite;
import protobuf_unittest.NonNestedExtension;
import protobuf_unittest.NonNestedExtensionLite;
import java.lang.reflect.Method;
@ -71,8 +69,6 @@ public class ExtensionRegistryFactoryTest extends TestCase {
void testAdd();
void testAdd_immutable();
void testExtensionRenamesKeywords();
}
/** Test implementations for the non-Lite usage of ExtensionRegistryFactory. */
@ -160,23 +156,6 @@ public class ExtensionRegistryFactoryTest extends TestCase {
} catch (IllegalArgumentException expected) {
}
}
@Override
public void testExtensionRenamesKeywords() {
assertTrue(NonNestedExtension.if_ instanceof GeneratedMessage.GeneratedExtension);
assertTrue(NestedExtension.MyNestedExtension.default_ instanceof GeneratedMessage.GeneratedExtension);
NonNestedExtension.MessageToBeExtended msg =
NonNestedExtension.MessageToBeExtended.newBuilder()
.setExtension(NonNestedExtension.if_, "!fi")
.build();
assertEquals("!fi", msg.getExtension(NonNestedExtension.if_));
msg = NonNestedExtension.MessageToBeExtended.newBuilder()
.setExtension(NestedExtension.MyNestedExtension.default_, 8)
.build();
assertEquals(8, msg.getExtension(NestedExtension.MyNestedExtension.default_).intValue());
}
}
/** Test implementations for the Lite usage of ExtensionRegistryFactory. */
@ -223,23 +202,6 @@ public class ExtensionRegistryFactoryTest extends TestCase {
} catch (UnsupportedOperationException expected) {
}
}
@Override
public void testExtensionRenamesKeywords() {
assertTrue(NonNestedExtensionLite.package_ instanceof GeneratedMessageLite.GeneratedExtension);
assertTrue(NestedExtensionLite.MyNestedExtensionLite.private_ instanceof GeneratedMessageLite.GeneratedExtension);
NonNestedExtensionLite.MessageLiteToBeExtended msg =
NonNestedExtensionLite.MessageLiteToBeExtended.newBuilder()
.setExtension(NonNestedExtensionLite.package_, true)
.build();
assertTrue(msg.getExtension(NonNestedExtensionLite.package_));
msg = NonNestedExtensionLite.MessageLiteToBeExtended.newBuilder()
.setExtension(NestedExtensionLite.MyNestedExtensionLite.private_, 2.4)
.build();
assertEquals(2.4, msg.getExtension(NestedExtensionLite.MyNestedExtensionLite.private_), 0.001);
}
}
/** Defines a suite of tests which the JUnit3 runner retrieves by reflection. */
@ -311,7 +273,10 @@ public class ExtensionRegistryFactoryTest extends TestCase {
resolveClass(loadedClass);
}
}
} catch (ClassNotFoundException e) {
} catch (ClassNotFoundException | SecurityException e) {
// Java 8+ would throw a SecurityException if we attempt to find a loaded class from
// java.lang.* package. We don't really care about those anyway, so just delegate to the
// parent class loader.
loadedClass = super.loadClass(name, resolve);
}
return loadedClass;

View File

@ -0,0 +1,894 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertArrayEquals;
import map_lite_test.MapTestProto.BizarroTestMap;
import map_lite_test.MapTestProto.TestMap;
import map_lite_test.MapTestProto.TestMap.MessageValue;
import map_lite_test.MapTestProto.TestMapOrBuilder;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import junit.framework.TestCase;
/** Unit tests for map fields. */
public final class MapLiteTest extends TestCase {
private void setMapValues(TestMap.Builder builder) {
builder
.putInt32ToInt32Field(1, 11)
.putInt32ToInt32Field(2, 22)
.putInt32ToInt32Field(3, 33)
.putInt32ToStringField(1, "11")
.putInt32ToStringField(2, "22")
.putInt32ToStringField(3, "33")
.putInt32ToBytesField(1, TestUtil.toBytes("11"))
.putInt32ToBytesField(2, TestUtil.toBytes("22"))
.putInt32ToBytesField(3, TestUtil.toBytes("33"))
.putInt32ToEnumField(1, TestMap.EnumValue.FOO)
.putInt32ToEnumField(2, TestMap.EnumValue.BAR)
.putInt32ToEnumField(3, TestMap.EnumValue.BAZ)
.putInt32ToMessageField(1, MessageValue.newBuilder().setValue(11).build())
.putInt32ToMessageField(2, MessageValue.newBuilder().setValue(22).build())
.putInt32ToMessageField(3, MessageValue.newBuilder().setValue(33).build())
.putStringToInt32Field("1", 11)
.putStringToInt32Field("2", 22)
.putStringToInt32Field("3", 33);
}
public void testSetMapValues() {
TestMap.Builder usingMutableMapBuilder = TestMap.newBuilder();
setMapValues(usingMutableMapBuilder);
TestMap usingMutableMap = usingMutableMapBuilder.build();
assertMapValuesSet(usingMutableMap);
TestMap.Builder usingAccessorsBuilder = TestMap.newBuilder();
setMapValues(usingAccessorsBuilder);
TestMap usingAccessors = usingAccessorsBuilder.build();
assertMapValuesSet(usingAccessors);
assertEquals(usingAccessors, usingMutableMap);
}
private void copyMapValues(TestMap source, TestMap.Builder destination) {
destination
.putAllInt32ToInt32Field(source.getInt32ToInt32Field())
.putAllInt32ToStringField(source.getInt32ToStringField())
.putAllInt32ToBytesField(source.getInt32ToBytesField())
.putAllInt32ToEnumField(source.getInt32ToEnumField())
.putAllInt32ToMessageField(source.getInt32ToMessageField())
.putAllStringToInt32Field(source.getStringToInt32Field());
}
private void assertMapValuesSet(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(11, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(22, message.getInt32ToInt32Field().get(2).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("11", message.getInt32ToStringField().get(1));
assertEquals("22", message.getInt32ToStringField().get(2));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("11"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("22"), message.getInt32ToBytesField().get(2));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(2));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(11, message.getInt32ToMessageField().get(1).getValue());
assertEquals(22, message.getInt32ToMessageField().get(2).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(11, message.getStringToInt32Field().get("1").intValue());
assertEquals(22, message.getStringToInt32Field().get("2").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
}
private void updateMapValues(TestMap.Builder builder) {
builder
.putInt32ToInt32Field(1, 111)
.removeInt32ToInt32Field(2)
.putInt32ToInt32Field(4, 44)
.putInt32ToStringField(1, "111")
.removeInt32ToStringField(2)
.putInt32ToStringField(4, "44")
.putInt32ToBytesField(1, TestUtil.toBytes("111"))
.removeInt32ToBytesField(2)
.putInt32ToBytesField(4, TestUtil.toBytes("44"))
.putInt32ToEnumField(1, TestMap.EnumValue.BAR)
.removeInt32ToEnumField(2)
.putInt32ToEnumField(4, TestMap.EnumValue.QUX)
.putInt32ToMessageField(1, MessageValue.newBuilder().setValue(111).build())
.removeInt32ToMessageField(2)
.putInt32ToMessageField(4, MessageValue.newBuilder().setValue(44).build())
.putStringToInt32Field("1", 111)
.removeStringToInt32Field("2")
.putStringToInt32Field("4", 44);
}
public void testUpdateMapValues() {
TestMap.Builder mapBuilder = TestMap.newBuilder();
setMapValues(mapBuilder);
TestMap map = mapBuilder.build();
assertMapValuesSet(map);
mapBuilder = map.toBuilder();
updateMapValues(mapBuilder);
map = mapBuilder.build();
assertMapValuesUpdated(map);
}
private void assertMapValuesUpdated(TestMap message) {
assertEquals(3, message.getInt32ToInt32Field().size());
assertEquals(111, message.getInt32ToInt32Field().get(1).intValue());
assertEquals(33, message.getInt32ToInt32Field().get(3).intValue());
assertEquals(44, message.getInt32ToInt32Field().get(4).intValue());
assertEquals(3, message.getInt32ToStringField().size());
assertEquals("111", message.getInt32ToStringField().get(1));
assertEquals("33", message.getInt32ToStringField().get(3));
assertEquals("44", message.getInt32ToStringField().get(4));
assertEquals(3, message.getInt32ToBytesField().size());
assertEquals(TestUtil.toBytes("111"), message.getInt32ToBytesField().get(1));
assertEquals(TestUtil.toBytes("33"), message.getInt32ToBytesField().get(3));
assertEquals(TestUtil.toBytes("44"), message.getInt32ToBytesField().get(4));
assertEquals(3, message.getInt32ToEnumField().size());
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.BAZ, message.getInt32ToEnumField().get(3));
assertEquals(TestMap.EnumValue.QUX, message.getInt32ToEnumField().get(4));
assertEquals(3, message.getInt32ToMessageField().size());
assertEquals(111, message.getInt32ToMessageField().get(1).getValue());
assertEquals(33, message.getInt32ToMessageField().get(3).getValue());
assertEquals(44, message.getInt32ToMessageField().get(4).getValue());
assertEquals(3, message.getStringToInt32Field().size());
assertEquals(111, message.getStringToInt32Field().get("1").intValue());
assertEquals(33, message.getStringToInt32Field().get("3").intValue());
assertEquals(44, message.getStringToInt32Field().get("4").intValue());
}
private void assertMapValuesCleared(TestMapOrBuilder testMapOrBuilder) {
assertEquals(0, testMapOrBuilder.getInt32ToInt32Field().size());
assertEquals(0, testMapOrBuilder.getInt32ToInt32FieldCount());
assertEquals(0, testMapOrBuilder.getInt32ToStringField().size());
assertEquals(0, testMapOrBuilder.getInt32ToStringFieldCount());
assertEquals(0, testMapOrBuilder.getInt32ToBytesField().size());
assertEquals(0, testMapOrBuilder.getInt32ToBytesFieldCount());
assertEquals(0, testMapOrBuilder.getInt32ToEnumField().size());
assertEquals(0, testMapOrBuilder.getInt32ToEnumFieldCount());
assertEquals(0, testMapOrBuilder.getInt32ToMessageField().size());
assertEquals(0, testMapOrBuilder.getInt32ToMessageFieldCount());
assertEquals(0, testMapOrBuilder.getStringToInt32Field().size());
assertEquals(0, testMapOrBuilder.getStringToInt32FieldCount());
}
public void testSanityCopyOnWrite() throws InvalidProtocolBufferException {
// Since builders are implemented as a thin wrapper around a message
// instance, we attempt to verify that we can't cause the builder to modify
// a produced message.
TestMap.Builder builder = TestMap.newBuilder();
TestMap message = builder.build();
builder.putInt32ToInt32Field(1, 2);
assertTrue(message.getInt32ToInt32Field().isEmpty());
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
message = builder.build();
builder.putInt32ToInt32Field(2, 3);
assertEquals(newMap(1, 2), message.getInt32ToInt32Field());
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
}
public void testGetMapIsImmutable() {
TestMap.Builder builder = TestMap.newBuilder();
assertMapsAreImmutable(builder);
assertMapsAreImmutable(builder.build());
setMapValues(builder);
assertMapsAreImmutable(builder);
assertMapsAreImmutable(builder.build());
}
private void assertMapsAreImmutable(TestMapOrBuilder testMapOrBuilder) {
assertImmutable(testMapOrBuilder.getInt32ToInt32Field(), 1, 2);
assertImmutable(testMapOrBuilder.getInt32ToStringField(), 1, "2");
assertImmutable(testMapOrBuilder.getInt32ToBytesField(), 1, TestUtil.toBytes("2"));
assertImmutable(testMapOrBuilder.getInt32ToEnumField(), 1, TestMap.EnumValue.FOO);
assertImmutable(
testMapOrBuilder.getInt32ToMessageField(), 1, MessageValue.getDefaultInstance());
assertImmutable(testMapOrBuilder.getStringToInt32Field(), "1", 2);
}
private <K, V> void assertImmutable(Map<K, V> map, K key, V value) {
try {
map.put(key, value);
fail();
} catch (UnsupportedOperationException e) {
// expected
}
if (!map.isEmpty()) {
try {
map.entrySet().remove(map.entrySet().iterator().next());
fail();
} catch (UnsupportedOperationException e) {
// expected
}
}
}
public void testMapFieldClear() {
TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2);
builder.clearInt32ToInt32Field();
assertEquals(0, builder.getInt32ToInt32FieldCount());
}
public void testMutableMapLifecycle() {
TestMap.Builder builder = TestMap.newBuilder().putInt32ToInt32Field(1, 2);
assertEquals(newMap(1, 2), builder.build().getInt32ToInt32Field());
assertEquals(newMap(1, 2), builder.getInt32ToInt32Field());
builder.putInt32ToInt32Field(2, 3);
assertEquals(newMap(1, 2, 2, 3), builder.getInt32ToInt32Field());
builder.putInt32ToEnumField(1, TestMap.EnumValue.BAR);
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.build().getInt32ToEnumField());
assertEquals(newMap(1, TestMap.EnumValue.BAR), builder.getInt32ToEnumField());
builder.putInt32ToEnumField(2, TestMap.EnumValue.FOO);
assertEquals(
newMap(1, TestMap.EnumValue.BAR, 2, TestMap.EnumValue.FOO), builder.getInt32ToEnumField());
builder.putInt32ToStringField(1, "1");
assertEquals(newMap(1, "1"), builder.build().getInt32ToStringField());
assertEquals(newMap(1, "1"), builder.getInt32ToStringField());
builder.putInt32ToStringField(2, "2");
assertEquals(newMap(1, "1", 2, "2"), builder.getInt32ToStringField());
builder.putInt32ToMessageField(1, TestMap.MessageValue.getDefaultInstance());
assertEquals(
newMap(1, TestMap.MessageValue.getDefaultInstance()),
builder.build().getInt32ToMessageField());
assertEquals(
newMap(1, TestMap.MessageValue.getDefaultInstance()), builder.getInt32ToMessageField());
builder.putInt32ToMessageField(2, TestMap.MessageValue.getDefaultInstance());
assertEquals(
newMap(
1,
TestMap.MessageValue.getDefaultInstance(),
2,
TestMap.MessageValue.getDefaultInstance()),
builder.getInt32ToMessageField());
}
public void testGettersAndSetters() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
TestMap message = builder.build();
assertMapValuesCleared(message);
builder = message.toBuilder();
setMapValues(builder);
message = builder.build();
assertMapValuesSet(message);
builder = message.toBuilder();
updateMapValues(builder);
message = builder.build();
assertMapValuesUpdated(message);
builder = message.toBuilder();
builder.clear();
assertMapValuesCleared(builder);
message = builder.build();
assertMapValuesCleared(message);
}
public void testPutAll() throws Exception {
TestMap.Builder sourceBuilder = TestMap.newBuilder();
setMapValues(sourceBuilder);
TestMap source = sourceBuilder.build();
assertMapValuesSet(source);
TestMap.Builder destination = TestMap.newBuilder();
copyMapValues(source, destination);
assertMapValuesSet(destination.build());
}
public void testPutAllForUnknownEnumValues() throws Exception {
TestMap.Builder sourceBuilder =
TestMap.newBuilder()
.putInt32ToEnumFieldValue(0, 0)
.putInt32ToEnumFieldValue(1, 1)
.putAllInt32ToEnumFieldValue(newMap(2, 1000)); // unknown value.
TestMap source = sourceBuilder.build();
TestMap.Builder destinationBuilder = TestMap.newBuilder();
destinationBuilder.putAllInt32ToEnumFieldValue(source.getInt32ToEnumFieldValue());
TestMap destination = destinationBuilder.build();
assertEquals(0, destination.getInt32ToEnumFieldValue().get(0).intValue());
assertEquals(1, destination.getInt32ToEnumFieldValue().get(1).intValue());
assertEquals(1000, destination.getInt32ToEnumFieldValue().get(2).intValue());
assertEquals(3, destination.getInt32ToEnumFieldCount());
}
public void testPutForUnknownEnumValues() throws Exception {
TestMap.Builder builder =
TestMap.newBuilder()
.putInt32ToEnumFieldValue(0, 0)
.putInt32ToEnumFieldValue(1, 1)
.putInt32ToEnumFieldValue(2, 1000); // unknown value.
TestMap message = builder.build();
assertEquals(0, message.getInt32ToEnumFieldValueOrThrow(0));
assertEquals(1, message.getInt32ToEnumFieldValueOrThrow(1));
assertEquals(1000, message.getInt32ToEnumFieldValueOrThrow(2));
assertEquals(3, message.getInt32ToEnumFieldCount());
}
public void testPutChecksNullKeysAndValues() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
try {
builder.putInt32ToStringField(1, null);
fail();
} catch (NullPointerException e) {
// expected.
}
try {
builder.putInt32ToBytesField(1, null);
fail();
} catch (NullPointerException e) {
// expected.
}
try {
builder.putInt32ToEnumField(1, null);
fail();
} catch (NullPointerException e) {
// expected.
}
try {
builder.putInt32ToMessageField(1, null);
fail();
} catch (NullPointerException e) {
// expected.
}
try {
builder.putStringToInt32Field(null, 1);
fail();
} catch (NullPointerException e) {
// expected.
}
}
public void testSerializeAndParse() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
setMapValues(builder);
TestMap message = builder.build();
assertEquals(message.getSerializedSize(), message.toByteString().size());
message = TestMap.parser().parseFrom(message.toByteString());
assertMapValuesSet(message);
builder = message.toBuilder();
updateMapValues(builder);
message = builder.build();
assertEquals(message.getSerializedSize(), message.toByteString().size());
message = TestMap.parser().parseFrom(message.toByteString());
assertMapValuesUpdated(message);
builder = message.toBuilder();
builder.clear();
message = builder.build();
assertEquals(message.getSerializedSize(), message.toByteString().size());
message = TestMap.parser().parseFrom(message.toByteString());
assertMapValuesCleared(message);
}
private TestMap tryParseTestMap(BizarroTestMap bizarroMap) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
CodedOutputStream output = CodedOutputStream.newInstance(byteArrayOutputStream);
bizarroMap.writeTo(output);
output.flush();
return TestMap.parser().parseFrom(ByteString.copyFrom(byteArrayOutputStream.toByteArray()));
}
public void testParseError() throws Exception {
ByteString bytes = TestUtil.toBytes("SOME BYTES");
String stringKey = "a string key";
TestMap map =
tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToInt32Field(5, bytes).build());
assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1));
map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToStringField(stringKey, 5).build());
assertEquals("", map.getInt32ToStringFieldOrDefault(0, null));
map = tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToBytesField(stringKey, 5).build());
assertEquals(map.getInt32ToBytesFieldOrDefault(0, null), ByteString.EMPTY);
map =
tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToEnumField(stringKey, bytes).build());
assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null));
try {
tryParseTestMap(BizarroTestMap.newBuilder().putInt32ToMessageField(stringKey, bytes).build());
fail();
} catch (InvalidProtocolBufferException expected) {
assertTrue(expected.getUnfinishedMessage() instanceof TestMap);
map = (TestMap) expected.getUnfinishedMessage();
assertTrue(map.getInt32ToMessageField().isEmpty());
}
map =
tryParseTestMap(
BizarroTestMap.newBuilder().putStringToInt32Field(stringKey, bytes).build());
assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1));
}
public void testMergeFrom() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
setMapValues(builder);
TestMap message = builder.build();
TestMap.Builder other = TestMap.newBuilder();
other.mergeFrom(message);
assertMapValuesSet(other.build());
}
public void testEqualsAndHashCode() throws Exception {
// Test that generated equals() and hashCode() will disregard the order
// of map entries when comparing/hashing map fields.
// We can't control the order of elements in a HashMap. The best we can do
// here is to add elements in different order.
TestMap.Builder b1 =
TestMap.newBuilder()
.putInt32ToInt32Field(1, 2)
.putInt32ToInt32Field(3, 4)
.putInt32ToInt32Field(5, 6);
TestMap m1 = b1.build();
TestMap.Builder b2 =
TestMap.newBuilder()
.putInt32ToInt32Field(5, 6)
.putInt32ToInt32Field(1, 2)
.putInt32ToInt32Field(3, 4);
TestMap m2 = b2.build();
assertEquals(m1, m2);
assertEquals(m1.hashCode(), m2.hashCode());
// Make sure we did compare map fields.
b2.putInt32ToInt32Field(1, 0);
m2 = b2.build();
assertFalse(m1.equals(m2));
// Don't check m1.hashCode() != m2.hashCode() because it's not guaranteed
// to be different.
// Regression test for b/18549190: if a map is a subset of the other map,
// equals() should return false.
b2.removeInt32ToInt32Field(1);
m2 = b2.build();
assertFalse(m1.equals(m2));
assertFalse(m2.equals(m1));
}
public void testUnknownEnumValues() throws Exception {
TestMap.Builder builder =
TestMap.newBuilder()
.putInt32ToEnumFieldValue(0, 0)
.putInt32ToEnumFieldValue(1, 1)
.putInt32ToEnumFieldValue(2, 1000); // unknown value.
TestMap message = builder.build();
assertEquals(TestMap.EnumValue.FOO, message.getInt32ToEnumField().get(0));
assertEquals(TestMap.EnumValue.BAR, message.getInt32ToEnumField().get(1));
assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2));
builder.putAllInt32ToEnumFieldValue(newMap(2, 1000)); // unknown value.
message = builder.build();
assertEquals(TestMap.EnumValue.UNRECOGNIZED, message.getInt32ToEnumField().get(2));
// Unknown enum values should be preserved after:
// 1. Serialization and parsing.
// 2. toBuild().
// 3. mergeFrom().
message = TestMap.parseFrom(message.toByteString());
assertEquals(1000, message.getInt32ToEnumFieldValue().get(2).intValue());
builder = message.toBuilder();
assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
builder = TestMap.newBuilder().mergeFrom(message);
assertEquals(1000, builder.getInt32ToEnumFieldValue().get(2).intValue());
// hashCode()/equals() should take unknown enum values into account.
builder.putAllInt32ToEnumFieldValue(newMap(2, 1001));
TestMap message2 = builder.build();
assertFalse(message.hashCode() == message2.hashCode());
assertFalse(message.equals(message2));
// Unknown values will be converted to UNRECOGNIZED so the resulted enum map
// should be the same.
assertEquals(message2.getInt32ToEnumField(), message.getInt32ToEnumField());
}
public void testIterationOrder() throws Exception {
TestMap.Builder builder = TestMap.newBuilder();
setMapValues(builder);
TestMap message = builder.build();
assertEquals(
Arrays.asList("1", "2", "3"), new ArrayList<>(message.getStringToInt32Field().keySet()));
}
public void testGetMap() {
TestMap.Builder builder = TestMap.newBuilder();
setMapValues(builder);
TestMap message = builder.build();
assertEquals(message.getStringToInt32Field(), message.getStringToInt32FieldMap());
assertEquals(message.getInt32ToBytesField(), message.getInt32ToBytesFieldMap());
assertEquals(message.getInt32ToEnumField(), message.getInt32ToEnumFieldMap());
assertEquals(message.getInt32ToEnumFieldValue(), message.getInt32ToEnumFieldValueMap());
assertEquals(message.getInt32ToMessageField(), message.getInt32ToMessageFieldMap());
}
public void testContains() {
TestMap.Builder builder = TestMap.newBuilder();
setMapValues(builder);
assertMapContainsSetValues(builder);
assertMapContainsSetValues(builder.build());
}
private void assertMapContainsSetValues(TestMapOrBuilder testMapOrBuilder) {
assertTrue(testMapOrBuilder.containsInt32ToInt32Field(1));
assertTrue(testMapOrBuilder.containsInt32ToInt32Field(2));
assertTrue(testMapOrBuilder.containsInt32ToInt32Field(3));
assertFalse(testMapOrBuilder.containsInt32ToInt32Field(-1));
assertTrue(testMapOrBuilder.containsInt32ToStringField(1));
assertTrue(testMapOrBuilder.containsInt32ToStringField(2));
assertTrue(testMapOrBuilder.containsInt32ToStringField(3));
assertFalse(testMapOrBuilder.containsInt32ToStringField(-1));
assertTrue(testMapOrBuilder.containsInt32ToBytesField(1));
assertTrue(testMapOrBuilder.containsInt32ToBytesField(2));
assertTrue(testMapOrBuilder.containsInt32ToBytesField(3));
assertFalse(testMapOrBuilder.containsInt32ToBytesField(-1));
assertTrue(testMapOrBuilder.containsInt32ToEnumField(1));
assertTrue(testMapOrBuilder.containsInt32ToEnumField(2));
assertTrue(testMapOrBuilder.containsInt32ToEnumField(3));
assertFalse(testMapOrBuilder.containsInt32ToEnumField(-1));
assertTrue(testMapOrBuilder.containsInt32ToMessageField(1));
assertTrue(testMapOrBuilder.containsInt32ToMessageField(2));
assertTrue(testMapOrBuilder.containsInt32ToMessageField(3));
assertFalse(testMapOrBuilder.containsInt32ToMessageField(-1));
assertTrue(testMapOrBuilder.containsStringToInt32Field("1"));
assertTrue(testMapOrBuilder.containsStringToInt32Field("2"));
assertTrue(testMapOrBuilder.containsStringToInt32Field("3"));
assertFalse(testMapOrBuilder.containsStringToInt32Field("-1"));
}
public void testCount() {
TestMap.Builder builder = TestMap.newBuilder();
assertMapCounts(0, builder);
setMapValues(builder);
assertMapCounts(3, builder);
TestMap message = builder.build();
assertMapCounts(3, message);
builder = message.toBuilder().putInt32ToInt32Field(4, 44);
assertEquals(4, builder.getInt32ToInt32FieldCount());
assertEquals(4, builder.build().getInt32ToInt32FieldCount());
// already present - should be unchanged
builder.putInt32ToInt32Field(4, 44);
assertEquals(4, builder.getInt32ToInt32FieldCount());
}
private void assertMapCounts(int expectedCount, TestMapOrBuilder testMapOrBuilder) {
assertEquals(expectedCount, testMapOrBuilder.getInt32ToInt32FieldCount());
assertEquals(expectedCount, testMapOrBuilder.getInt32ToStringFieldCount());
assertEquals(expectedCount, testMapOrBuilder.getInt32ToBytesFieldCount());
assertEquals(expectedCount, testMapOrBuilder.getInt32ToEnumFieldCount());
assertEquals(expectedCount, testMapOrBuilder.getInt32ToMessageFieldCount());
assertEquals(expectedCount, testMapOrBuilder.getStringToInt32FieldCount());
}
public void testGetOrDefault() {
TestMap.Builder builder = TestMap.newBuilder();
assertMapCounts(0, builder);
setMapValues(builder);
doTestGetOrDefault(builder);
doTestGetOrDefault(builder.build());
}
public void doTestGetOrDefault(TestMapOrBuilder testMapOrBuilder) {
assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(1, -11));
assertEquals(-11, testMapOrBuilder.getInt32ToInt32FieldOrDefault(-1, -11));
assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrDefault(1, "-11"));
assertNull("-11", testMapOrBuilder.getInt32ToStringFieldOrDefault(-1, null));
assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrDefault(1, null));
assertNull(testMapOrBuilder.getInt32ToBytesFieldOrDefault(-1, null));
assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrDefault(1, null));
assertNull(testMapOrBuilder.getInt32ToEnumFieldOrDefault(-1, null));
assertEquals(
TestMap.EnumValue.BAR.getNumber(),
testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(2, -1));
assertEquals(-1, testMapOrBuilder.getInt32ToEnumFieldValueOrDefault(-1000, -1));
assertEquals(
MessageValue.newBuilder().setValue(11).build(),
testMapOrBuilder.getInt32ToMessageFieldOrDefault(1, null));
assertNull(testMapOrBuilder.getInt32ToMessageFieldOrDefault(-1, null));
assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrDefault("1", -11));
assertEquals(-11, testMapOrBuilder.getStringToInt32FieldOrDefault("-1", -11));
try {
testMapOrBuilder.getStringToInt32FieldOrDefault(null, -11);
fail();
} catch (NullPointerException e) {
// expected
}
}
public void testGetOrThrow() {
TestMap.Builder builder = TestMap.newBuilder();
assertMapCounts(0, builder);
setMapValues(builder);
doTestGetOrDefault(builder);
doTestGetOrDefault(builder.build());
}
public void doTestGetOrThrow(TestMapOrBuilder testMapOrBuilder) {
assertEquals(11, testMapOrBuilder.getInt32ToInt32FieldOrThrow(1));
try {
testMapOrBuilder.getInt32ToInt32FieldOrThrow(-1);
fail();
} catch (IllegalArgumentException e) {
// expected
}
assertEquals("11", testMapOrBuilder.getInt32ToStringFieldOrThrow(1));
try {
testMapOrBuilder.getInt32ToStringFieldOrThrow(-1);
fail();
} catch (IllegalArgumentException e) {
// expected
}
assertEquals(TestUtil.toBytes("11"), testMapOrBuilder.getInt32ToBytesFieldOrThrow(1));
try {
testMapOrBuilder.getInt32ToBytesFieldOrThrow(-1);
fail();
} catch (IllegalArgumentException e) {
// expected
}
assertEquals(TestMap.EnumValue.FOO, testMapOrBuilder.getInt32ToEnumFieldOrThrow(1));
try {
testMapOrBuilder.getInt32ToEnumFieldOrThrow(-1);
fail();
} catch (IllegalArgumentException e) {
// expected
}
assertEquals(
TestMap.EnumValue.BAR.getNumber(), testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(2));
try {
testMapOrBuilder.getInt32ToEnumFieldValueOrThrow(-1);
fail();
} catch (IllegalArgumentException e) {
// expected
}
assertEquals(
MessageValue.newBuilder().setValue(11).build(),
testMapOrBuilder.getInt32ToMessageFieldOrThrow(1));
try {
testMapOrBuilder.getInt32ToMessageFieldOrThrow(-1);
fail();
} catch (IllegalArgumentException e) {
// expected
}
assertEquals(11, testMapOrBuilder.getStringToInt32FieldOrThrow("1"));
try {
testMapOrBuilder.getStringToInt32FieldOrThrow("-1");
fail();
} catch (IllegalArgumentException e) {
// expected
}
try {
testMapOrBuilder.getStringToInt32FieldOrThrow(null);
fail();
} catch (NullPointerException e) {
// expected
}
}
public void testPut() {
TestMap.Builder builder = TestMap.newBuilder();
builder.putInt32ToInt32Field(1, 11);
assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
builder.putInt32ToStringField(1, "a");
assertEquals("a", builder.getInt32ToStringFieldOrThrow(1));
try {
builder.putInt32ToStringField(1, null);
fail();
} catch (NullPointerException e) {
// expected
}
builder.putInt32ToBytesField(1, TestUtil.toBytes("11"));
assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
try {
builder.putInt32ToBytesField(1, null);
fail();
} catch (NullPointerException e) {
// expected
}
builder.putInt32ToEnumField(1, TestMap.EnumValue.FOO);
assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
try {
builder.putInt32ToEnumField(1, null);
fail();
} catch (NullPointerException e) {
// expected
}
builder.putStringToInt32Field("a", 1);
assertEquals(1, builder.getStringToInt32FieldOrThrow("a"));
try {
builder.putStringToInt32Field(null, -1);
} catch (NullPointerException e) {
// expected
}
}
public void testRemove() {
TestMap.Builder builder = TestMap.newBuilder();
setMapValues(builder);
assertEquals(11, builder.getInt32ToInt32FieldOrThrow(1));
for (int times = 0; times < 2; times++) {
builder.removeInt32ToInt32Field(1);
assertEquals(-1, builder.getInt32ToInt32FieldOrDefault(1, -1));
}
assertEquals("11", builder.getInt32ToStringFieldOrThrow(1));
for (int times = 0; times < 2; times++) {
builder.removeInt32ToStringField(1);
assertNull(builder.getInt32ToStringFieldOrDefault(1, null));
}
assertEquals(TestUtil.toBytes("11"), builder.getInt32ToBytesFieldOrThrow(1));
for (int times = 0; times < 2; times++) {
builder.removeInt32ToBytesField(1);
assertNull(builder.getInt32ToBytesFieldOrDefault(1, null));
}
assertEquals(TestMap.EnumValue.FOO, builder.getInt32ToEnumFieldOrThrow(1));
for (int times = 0; times < 2; times++) {
builder.removeInt32ToEnumField(1);
assertNull(builder.getInt32ToEnumFieldOrDefault(1, null));
}
assertEquals(11, builder.getStringToInt32FieldOrThrow("1"));
for (int times = 0; times < 2; times++) {
builder.removeStringToInt32Field("1");
assertEquals(-1, builder.getStringToInt32FieldOrDefault("1", -1));
}
try {
builder.removeStringToInt32Field(null);
fail();
} catch (NullPointerException e) {
// expected
}
}
private static <K, V> Map<K, V> newMap(K key1, V value1) {
Map<K, V> map = new HashMap<>();
map.put(key1, value1);
return map;
}
private static <K, V> Map<K, V> newMap(K key1, V value1, K key2, V value2) {
Map<K, V> map = new HashMap<>();
map.put(key1, value1);
map.put(key2, value2);
return map;
}
public void testMap_withNulls() {
TestMap.Builder builder = TestMap.newBuilder();
try {
builder.putStringToInt32Field(null, 3);
fail();
} catch (NullPointerException expected) {
}
try {
builder.putAllStringToInt32Field(newMap(null, 3, "hi", 4));
fail();
} catch (NullPointerException expected) {
}
try {
builder.putInt32ToMessageField(3, null);
fail();
} catch (NullPointerException expected) {
}
try {
builder.putAllInt32ToMessageField(
MapLiteTest.<Integer, MessageValue>newMap(4, null, 5, null));
fail();
} catch (NullPointerException expected) {
}
try {
builder.putAllInt32ToMessageField(null);
fail();
} catch (NullPointerException expected) {
}
assertArrayEquals(new byte[0], builder.build().toByteArray());
}
}

View File

@ -0,0 +1,232 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.PackedFieldTestProto.TestAllTypes;
import com.google.protobuf.PackedFieldTestProto.TestAllTypes.NestedEnum;
import com.google.protobuf.PackedFieldTestProto.TestUnpackedTypes;
import junit.framework.TestCase;
/** Tests primitive repeated fields in proto3 are packed in wire format. */
public class PackedFieldTest extends TestCase {
static final ByteString expectedPackedRawBytes =
ByteString.copyFrom(
new byte[] {
(byte) 0xFA,
0x01,
0x01,
0x01, // repeated int32
(byte) 0x82,
0x02,
0x01,
0x01, // repeated int64
(byte) 0x8A,
0x02,
0x01,
0x01, // repeated uint32
(byte) 0x92,
0x02,
0x01,
0x01, // repeated uint64
(byte) 0x9A,
0x02,
0x01,
0x02, // repeated sint32
(byte) 0xA2,
0x02,
0x01,
0x02, // repeated sint64
(byte) 0xAA,
0x02,
0x04,
0x01,
0x00,
0x00,
0x00, // repeated fixed32
(byte) 0xB2,
0x02,
0x08,
0x01,
0x00,
0x00,
0x00, // repeated fixed64
0x00,
0x00,
0x00,
0x00,
(byte) 0xBA,
0x02,
0x04,
0x01,
0x00,
0x00,
0x00, // repeated sfixed32
(byte) 0xC2,
0x02,
0x08,
0x01,
0x00,
0x00,
0x00, // repeated sfixed64
0x00,
0x00,
0x00,
0x00,
(byte) 0xCA,
0x02,
0x04,
0x00,
0x00,
(byte) 0x80,
0x3f, // repeated float
(byte) 0xD2,
0x02,
0x08,
0x00,
0x00,
0x00,
0x00, // repeated double
0x00,
0x00,
(byte) 0xf0,
0x3f,
(byte) 0xDA,
0x02,
0x01,
0x01, // repeated bool
(byte) 0x9A,
0x03,
0x01,
0x01 // repeated nested enum
});
static final ByteString expectedUnpackedRawBytes =
ByteString.copyFrom(
new byte[] {
0x08,
0x01, // repeated int32
0x10,
0x01, // repeated int64
0x18,
0x01, // repeated uint32
0x20,
0x01, // repeated uint64
0x28,
0x02, // repeated sint32
0x30,
0x02, // repeated sint64
0x3D,
0x01,
0x00,
0x00,
0x00, // repeated fixed32
0x41,
0x01,
0x00,
0x00,
0x00, // repeated fixed64
0x00,
0x00,
0x00,
0x00,
0x4D,
0x01,
0x00,
0x00,
0x00, // repeated sfixed32
0x51,
0x01,
0x00,
0x00,
0x00, // repeated sfixed64
0x00,
0x00,
0x00,
0x00,
0x5D,
0x00,
0x00,
(byte) 0x80,
0x3f, // repeated float
0x61,
0x00,
0x00,
0x00,
0x00, // repeated double
0x00,
0x00,
(byte) 0xf0,
0x3f,
0x68,
0x01, // repeated bool
0x70,
0x01, // repeated nested enum
});
public void testPackedGeneratedMessage() throws Exception {
TestAllTypes message = TestAllTypes.parseFrom(expectedPackedRawBytes);
assertEquals(expectedPackedRawBytes, message.toByteString());
}
public void testPackedDynamicMessageSerialize() throws Exception {
DynamicMessage message =
DynamicMessage.parseFrom(TestAllTypes.getDescriptor(), expectedPackedRawBytes);
assertEquals(expectedPackedRawBytes, message.toByteString());
}
public void testUnpackedGeneratedMessage() throws Exception {
TestUnpackedTypes message = TestUnpackedTypes.parseFrom(expectedUnpackedRawBytes);
assertEquals(expectedUnpackedRawBytes, message.toByteString());
}
public void testUnPackedDynamicMessageSerialize() throws Exception {
DynamicMessage message =
DynamicMessage.parseFrom(TestUnpackedTypes.getDescriptor(), expectedUnpackedRawBytes);
assertEquals(expectedUnpackedRawBytes, message.toByteString());
}
// Make sure we haven't screwed up the code generation for packing fields by default.
public void testPackedSerialization() throws Exception {
TestAllTypes message =
TestAllTypes.newBuilder()
.addRepeatedInt32(1234)
.addRepeatedNestedEnum(NestedEnum.BAR)
.build();
CodedInputStream in = CodedInputStream.newInstance(message.toByteArray());
while (!in.isAtEnd()) {
int tag = in.readTag();
assertEquals(WireFormat.WIRETYPE_LENGTH_DELIMITED, WireFormat.getTagWireType(tag));
in.skipField(tag);
}
}
}

View File

@ -0,0 +1,191 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.UnittestLite.TestAllTypesLite;
import com.google.protobuf.UnittestLite.TestPackedExtensionsLite;
import com.google.protobuf.UnittestLite.TestParsingMergeLite;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import junit.framework.TestCase;
public class ParserLiteTest extends TestCase {
private void assertRoundTripEquals(MessageLite message, ExtensionRegistryLite registry)
throws Exception {
final byte[] data = message.toByteArray();
final int offset = 20;
final int length = data.length;
final int padding = 30;
Parser<? extends MessageLite> parser = message.getParserForType();
assertEquals(message, parser.parseFrom(data, registry));
assertEquals(
message,
parser.parseFrom(generatePaddingArray(data, offset, padding), offset, length, registry));
assertEquals(message, parser.parseFrom(message.toByteString(), registry));
assertEquals(message, parser.parseFrom(new ByteArrayInputStream(data), registry));
assertEquals(message, parser.parseFrom(CodedInputStream.newInstance(data), registry));
assertEquals(
message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry));
}
@SuppressWarnings("unchecked")
private void assertRoundTripEquals(MessageLite message) throws Exception {
final byte[] data = message.toByteArray();
final int offset = 20;
final int length = data.length;
final int padding = 30;
Parser<MessageLite> parser = (Parser<MessageLite>) message.getParserForType();
assertEquals(message, parser.parseFrom(data));
assertEquals(
message, parser.parseFrom(generatePaddingArray(data, offset, padding), offset, length));
assertEquals(message, parser.parseFrom(message.toByteString()));
assertEquals(message, parser.parseFrom(new ByteArrayInputStream(data)));
assertEquals(message, parser.parseFrom(CodedInputStream.newInstance(data)));
assertEquals(message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer()));
}
private byte[] generatePaddingArray(byte[] data, int offset, int padding) {
byte[] result = new byte[offset + data.length + padding];
System.arraycopy(data, 0, result, offset, data.length);
return result;
}
public void testParseExtensionsLite() throws Exception {
assertRoundTripEquals(
TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
}
public void testParsePacked() throws Exception {
assertRoundTripEquals(TestUtil.getPackedSet());
assertRoundTripEquals(TestUtil.getPackedExtensionsSet(), TestUtil.getExtensionRegistry());
}
public void testParsePackedLite() throws Exception {
assertRoundTripEquals(
TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite());
}
public void testParseDelimitedToLite() throws Exception {
// Write MessageLite with packed extension fields.
TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet();
ByteArrayOutputStream output = new ByteArrayOutputStream();
packedMessage.writeDelimitedTo(output);
packedMessage.writeDelimitedTo(output);
InputStream input = new ByteArrayInputStream(output.toByteArray());
assertEquals(
packedMessage,
packedMessage
.getParserForType()
.parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite()));
assertEquals(
packedMessage,
packedMessage
.getParserForType()
.parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite()));
}
/** Helper method for {@link #testParsingMergeLite()}. */
private void assertMessageMerged(TestAllTypesLite allTypes) throws Exception {
assertEquals(3, allTypes.getOptionalInt32());
assertEquals(2, allTypes.getOptionalInt64());
assertEquals("hello", allTypes.getOptionalString());
}
public void testParsingMergeLite() throws Exception {
// Build messages.
TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder();
TestAllTypesLite msg1 = builder.setOptionalInt32(1).build();
builder.clear();
TestAllTypesLite msg2 = builder.setOptionalInt64(2).build();
builder.clear();
TestAllTypesLite msg3 = builder.setOptionalInt32(3).setOptionalString("hello").build();
// Build groups.
TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG1 =
TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder().setField1(msg1).build();
TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG2 =
TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder().setField1(msg2).build();
TestParsingMergeLite.RepeatedFieldsGenerator.Group1 optionalG3 =
TestParsingMergeLite.RepeatedFieldsGenerator.Group1.newBuilder().setField1(msg3).build();
TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG1 =
TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder().setField1(msg1).build();
TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG2 =
TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder().setField1(msg2).build();
TestParsingMergeLite.RepeatedFieldsGenerator.Group2 repeatedG3 =
TestParsingMergeLite.RepeatedFieldsGenerator.Group2.newBuilder().setField1(msg3).build();
// Assign and serialize RepeatedFieldsGenerator.
ByteString data =
TestParsingMergeLite.RepeatedFieldsGenerator.newBuilder()
.addField1(msg1)
.addField1(msg2)
.addField1(msg3)
.addField2(msg1)
.addField2(msg2)
.addField2(msg3)
.addField3(msg1)
.addField3(msg2)
.addField3(msg3)
.addGroup1(optionalG1)
.addGroup1(optionalG2)
.addGroup1(optionalG3)
.addGroup2(repeatedG1)
.addGroup2(repeatedG2)
.addGroup2(repeatedG3)
.addExt1(msg1)
.addExt1(msg2)
.addExt1(msg3)
.addExt2(msg1)
.addExt2(msg2)
.addExt2(msg3)
.build()
.toByteString();
// Parse TestParsingMergeLite.
ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
UnittestLite.registerAllExtensions(registry);
TestParsingMergeLite parsingMerge = TestParsingMergeLite.parser().parseFrom(data, registry);
// Required and optional fields should be merged.
assertMessageMerged(parsingMerge.getRequiredAllTypes());
assertMessageMerged(parsingMerge.getOptionalAllTypes());
assertMessageMerged(parsingMerge.getOptionalGroup().getOptionalGroupAllTypes());
assertMessageMerged(parsingMerge.getExtension(TestParsingMergeLite.optionalExt));
// Repeated fields should not be merged.
assertEquals(3, parsingMerge.getRepeatedAllTypesCount());
assertEquals(3, parsingMerge.getRepeatedGroupCount());
assertEquals(3, parsingMerge.getExtensionCount(TestParsingMergeLite.repeatedExt));
}
}

View File

@ -0,0 +1,171 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import com.google.protobuf.testing.Proto2Testing;
import com.google.protobuf.testing.Proto2Testing.Proto2Message;
import com.google.protobuf.testing.Proto2Testing.Proto2Message.TestEnum;
import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithExtensions;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class Proto2ExtensionLookupSchemaTest {
private byte[] data;
private ExtensionRegistry extensionRegistry;
@Before
public void setup() {
TestSchemas.registerGenericProto2Schemas();
Protobuf.getInstance().schemaFor(Proto2MessageWithExtensions.class);
data = new Proto2MessageFactory(10, 20, 1, 1).newMessage().toByteArray();
extensionRegistry = ExtensionRegistry.newInstance();
Proto2Testing.registerAllExtensions(extensionRegistry);
}
@Test
public void testExtensions() throws Exception {
Proto2MessageWithExtensions base =
Proto2MessageWithExtensions.parseFrom(data, extensionRegistry);
Proto2MessageWithExtensions message =
ExperimentalSerializationUtil.fromByteArray(
data, Proto2MessageWithExtensions.class, extensionRegistry);
assertEquals(base, message);
Proto2MessageWithExtensions roundtripMessage =
ExperimentalSerializationUtil.fromByteArray(
ExperimentalSerializationUtil.toByteArray(message),
Proto2MessageWithExtensions.class,
extensionRegistry);
assertEquals(base, roundtripMessage);
}
@Test
public void testUnknownEnum() throws Exception {
// Use unknown fields to hold invalid enum values.
UnknownFieldSetLite unknowns = UnknownFieldSetLite.newInstance();
final int outOfRange = 1000;
assertNull(TestEnum.forNumber(outOfRange));
unknowns.storeField(
WireFormat.makeTag(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) outOfRange);
unknowns.storeField(
WireFormat.makeTag(
Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) TestEnum.ONE_VALUE);
unknowns.storeField(
WireFormat.makeTag(
Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) outOfRange);
unknowns.storeField(
WireFormat.makeTag(
Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER, WireFormat.WIRETYPE_VARINT),
(long) TestEnum.TWO_VALUE);
{
// Construct a packed enum list.
int packedSize =
CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE)
+ CodedOutputStream.computeUInt32SizeNoTag(outOfRange)
+ CodedOutputStream.computeUInt32SizeNoTag(TestEnum.ONE_VALUE);
ByteString.CodedBuilder packedBuilder = ByteString.newCodedBuilder(packedSize);
CodedOutputStream packedOut = packedBuilder.getCodedOutput();
packedOut.writeEnumNoTag(TestEnum.ONE_VALUE);
packedOut.writeEnumNoTag(outOfRange);
packedOut.writeEnumNoTag(TestEnum.TWO_VALUE);
unknowns.storeField(
WireFormat.makeTag(
Proto2Message.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER,
WireFormat.WIRETYPE_LENGTH_DELIMITED),
packedBuilder.build());
}
int size = unknowns.getSerializedSize();
byte[] output = new byte[size];
CodedOutputStream codedOutput = CodedOutputStream.newInstance(output);
unknowns.writeTo(codedOutput);
codedOutput.flush();
Proto2MessageWithExtensions parsed =
ExperimentalSerializationUtil.fromByteArray(
output, Proto2MessageWithExtensions.class, extensionRegistry);
assertFalse(
"out-of-range singular enum should not be in message",
parsed.hasExtension(Proto2Testing.fieldEnum13));
{
List<Long> singularEnum =
parsed
.getUnknownFields()
.getField(Proto2Message.FIELD_ENUM_13_FIELD_NUMBER)
.getVarintList();
assertEquals(1, singularEnum.size());
assertEquals((Long) (long) outOfRange, singularEnum.get(0));
}
{
List<Long> repeatedEnum =
parsed
.getUnknownFields()
.getField(Proto2Message.FIELD_ENUM_LIST_30_FIELD_NUMBER)
.getVarintList();
assertEquals(1, repeatedEnum.size());
assertEquals((Long) (long) outOfRange, repeatedEnum.get(0));
}
{
List<Long> packedRepeatedEnum =
parsed
.getUnknownFields()
.getField(Proto2Message.FIELD_ENUM_LIST_PACKED_44_FIELD_NUMBER)
.getVarintList();
assertEquals(1, packedRepeatedEnum.size());
assertEquals((Long) (long) outOfRange, packedRepeatedEnum.get(0));
}
assertEquals(
"out-of-range repeated enum should not be in message",
2,
parsed.getExtension(Proto2Testing.fieldEnumList30).size());
assertEquals(TestEnum.ONE, parsed.getExtension(Proto2Testing.fieldEnumList30, 0));
assertEquals(TestEnum.TWO, parsed.getExtension(Proto2Testing.fieldEnumList30, 1));
assertEquals(
"out-of-range packed repeated enum should not be in message",
2,
parsed.getExtension(Proto2Testing.fieldEnumListPacked44).size());
assertEquals(TestEnum.ONE, parsed.getExtension(Proto2Testing.fieldEnumListPacked44, 0));
assertEquals(TestEnum.TWO, parsed.getExtension(Proto2Testing.fieldEnumListPacked44, 1));
}
}

View File

@ -0,0 +1,49 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class Proto2LiteSchemaTest extends AbstractProto2LiteSchemaTest {
@Override
protected Schema<Proto2MessageLite> schema() {
return TestSchemasLite.genericProto2LiteSchema;
}
@Override
protected void registerSchemas() {
TestSchemasLite.registerGenericProto2LiteSchemas();
}
}

View File

@ -0,0 +1,555 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.testing.Proto2Testing.Proto2Message;
import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithMaps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** Creates instances of {@link Proto2Message} based on the tree configuration. */
public final class Proto2MessageFactory implements ExperimentalMessageFactory<Proto2Message> {
private final int numRepeatedFields;
private final int branchingFactor;
private final Proto2MessageFactory nextLevel;
private final ExperimentalTestDataProvider data;
public Proto2MessageFactory(
int numRepeatedFields, int stringLength, int branchingFactor, int treeDepth) {
this(
new ExperimentalTestDataProvider(stringLength),
numRepeatedFields,
branchingFactor,
treeDepth);
}
private Proto2MessageFactory(
ExperimentalTestDataProvider data,
int numRepeatedFields,
int branchingFactor,
int treeDepth) {
this.numRepeatedFields = numRepeatedFields;
this.branchingFactor = branchingFactor;
this.data = data;
if (treeDepth > 0) {
nextLevel = new Proto2MessageFactory(data, numRepeatedFields, branchingFactor, treeDepth - 1);
} else {
nextLevel = null;
}
}
@Override
public ExperimentalTestDataProvider dataProvider() {
return data;
}
@Override
public Proto2Message newMessage() {
Proto2Message.Builder builder = Proto2Message.newBuilder();
builder.setFieldDouble1(data.getDouble());
builder.setFieldFloat2(data.getFloat());
builder.setFieldInt643(data.getLong());
builder.setFieldUint644(data.getLong());
builder.setFieldInt325(data.getInt());
builder.setFieldFixed646(data.getLong());
builder.setFieldFixed327(data.getInt());
builder.setFieldBool8(data.getBool());
builder.setFieldString9(data.getString());
// We don't populate the message field. Instead we apply the branching factor to the
// repeated message field below.
builder.setFieldBytes11(data.getBytes());
builder.setFieldUint3212(data.getInt());
builder.setFieldEnum13(Proto2Message.TestEnum.forNumber(data.getEnum()));
builder.setFieldSfixed3214(data.getInt());
builder.setFieldSfixed6415(data.getLong());
builder.setFieldSint3216(data.getInt());
builder.setFieldSint6417(data.getLong());
for (int i = 0; i < numRepeatedFields; ++i) {
builder.addFieldDoubleList18(data.getDouble());
builder.addFieldFloatList19(data.getFloat());
builder.addFieldInt64List20(data.getLong());
builder.addFieldUint64List21(data.getLong());
builder.addFieldInt32List22(data.getInt());
builder.addFieldFixed64List23(data.getLong());
builder.addFieldFixed32List24(data.getInt());
builder.addFieldBoolList25(data.getBool());
builder.addFieldStringList26(data.getString());
// Repeated message field is controlled by the branching factor below.
builder.addFieldBytesList28(data.getBytes());
builder.addFieldUint32List29(data.getInt());
builder.addFieldEnumList30(Proto2Message.TestEnum.forNumber(data.getEnum()));
builder.addFieldSfixed32List31(data.getInt());
builder.addFieldSfixed64List32(data.getLong());
builder.addFieldSint32List33(data.getInt());
builder.addFieldSint64List34(data.getLong());
builder.addFieldDoubleListPacked35(data.getDouble());
builder.addFieldFloatListPacked36(data.getFloat());
builder.addFieldInt64ListPacked37(data.getLong());
builder.addFieldUint64ListPacked38(data.getLong());
builder.addFieldInt32ListPacked39(data.getInt());
builder.addFieldFixed64ListPacked40(data.getLong());
builder.addFieldFixed32ListPacked41(data.getInt());
builder.addFieldBoolListPacked42(data.getBool());
builder.addFieldUint32ListPacked43(data.getInt());
builder.addFieldEnumListPacked44(Proto2Message.TestEnum.forNumber(data.getEnum()));
builder.addFieldSfixed32ListPacked45(data.getInt());
builder.addFieldSfixed64ListPacked46(data.getLong());
builder.addFieldSint32ListPacked47(data.getInt());
builder.addFieldSint64ListPacked48(data.getLong());
}
builder.setFieldGroup49(Proto2Message.FieldGroup49.newBuilder().setFieldInt3250(data.getInt()));
for (int i = 0; i < branchingFactor; ++i) {
builder.addFieldGroupList51(
Proto2Message.FieldGroupList51.newBuilder().setFieldInt3252(data.getInt()));
}
// Set all required fields.
populateRequiredFields(builder, INCLUDE_ALL_REQUIRED_FIELDS);
// Handle the branching factor.
if (nextLevel != null) {
for (int i = 0; i < branchingFactor; ++i) {
builder.addFieldMessageList27(nextLevel.newMessage());
}
}
return builder.build();
}
private interface MapValueProvider<T> {
public T getValue();
}
private final MapValueProvider<Integer> integerProvider =
new MapValueProvider<Integer>() {
@Override
public Integer getValue() {
return data.getInt();
}
};
private final MapValueProvider<Long> longProvider =
new MapValueProvider<Long>() {
@Override
public Long getValue() {
return data.getLong();
}
};
private final MapValueProvider<String> stringProvider =
new MapValueProvider<String>() {
@Override
public String getValue() {
return data.getString();
}
};
private final MapValueProvider<ByteString> bytesProvider =
new MapValueProvider<ByteString>() {
@Override
public ByteString getValue() {
return data.getBytes();
}
};
private final MapValueProvider<Boolean> booleanProvider =
new MapValueProvider<Boolean>() {
@Override
public Boolean getValue() {
return data.getBool();
}
};
private final MapValueProvider<Float> floatProvider =
new MapValueProvider<Float>() {
@Override
public Float getValue() {
return data.getFloat();
}
};
private final MapValueProvider<Double> doubleProvider =
new MapValueProvider<Double>() {
@Override
public Double getValue() {
return data.getDouble();
}
};
private final MapValueProvider<Proto2Message> messageProvider =
new MapValueProvider<Proto2Message>() {
@Override
public Proto2Message getValue() {
return newMessage();
}
};
private final MapValueProvider<Proto2Message.TestEnum> enumProvider =
new MapValueProvider<Proto2Message.TestEnum>() {
@Override
public Proto2Message.TestEnum getValue() {
return Proto2Message.TestEnum.forNumber(data.getEnum());
}
};
private <V> Map<Integer, V> populateIntegerMap(MapValueProvider<V> provider) {
Map<Integer, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getInt(), provider.getValue());
}
return map;
}
private <V> Map<Long, V> populateLongMap(MapValueProvider<V> provider) {
Map<Long, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getLong(), provider.getValue());
}
return map;
}
private <V> Map<String, V> populateStringMap(MapValueProvider<V> provider) {
Map<String, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getString(), provider.getValue());
}
return map;
}
private <V> Map<Boolean, V> populateBooleanMap(MapValueProvider<V> provider) {
Map<Boolean, V> map = new HashMap<>();
map.put(false, provider.getValue());
map.put(true, provider.getValue());
return map;
}
public Proto2MessageWithMaps newMessageWithMaps() {
Proto2MessageWithMaps.Builder builder = Proto2MessageWithMaps.newBuilder();
builder.putAllFieldMapBoolBool1(populateBooleanMap(booleanProvider));
builder.putAllFieldMapBoolBytes2(populateBooleanMap(bytesProvider));
builder.putAllFieldMapBoolDouble3(populateBooleanMap(doubleProvider));
builder.putAllFieldMapBoolEnum4(populateBooleanMap(enumProvider));
builder.putAllFieldMapBoolFixed325(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolFixed646(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolFloat7(populateBooleanMap(floatProvider));
builder.putAllFieldMapBoolInt328(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolInt649(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolMessage10(populateBooleanMap(messageProvider));
builder.putAllFieldMapBoolSfixed3211(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolSfixed6412(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolSint3213(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolSint6414(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolString15(populateBooleanMap(stringProvider));
builder.putAllFieldMapBoolUint3216(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolUint6417(populateBooleanMap(longProvider));
builder.putAllFieldMapFixed32Bool18(populateIntegerMap(booleanProvider));
builder.putAllFieldMapFixed32Bytes19(populateIntegerMap(bytesProvider));
builder.putAllFieldMapFixed32Double20(populateIntegerMap(doubleProvider));
builder.putAllFieldMapFixed32Enum21(populateIntegerMap(enumProvider));
builder.putAllFieldMapFixed32Fixed3222(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Fixed6423(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Float24(populateIntegerMap(floatProvider));
builder.putAllFieldMapFixed32Int3225(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Int6426(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Message27(populateIntegerMap(messageProvider));
builder.putAllFieldMapFixed32Sfixed3228(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Sfixed6429(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Sint3230(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Sint6431(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32String32(populateIntegerMap(stringProvider));
builder.putAllFieldMapFixed32Uint3233(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Uint6434(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed64Bool35(populateLongMap(booleanProvider));
builder.putAllFieldMapFixed64Bytes36(populateLongMap(bytesProvider));
builder.putAllFieldMapFixed64Double37(populateLongMap(doubleProvider));
builder.putAllFieldMapFixed64Enum38(populateLongMap(enumProvider));
builder.putAllFieldMapFixed64Fixed3239(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Fixed6440(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Float41(populateLongMap(floatProvider));
builder.putAllFieldMapFixed64Int3242(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Int6443(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Message44(populateLongMap(messageProvider));
builder.putAllFieldMapFixed64Sfixed3245(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Sfixed6446(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Sint3247(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Sint6448(populateLongMap(longProvider));
builder.putAllFieldMapFixed64String49(populateLongMap(stringProvider));
builder.putAllFieldMapFixed64Uint3250(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Uint6451(populateLongMap(longProvider));
builder.putAllFieldMapInt32Bool52(populateIntegerMap(booleanProvider));
builder.putAllFieldMapInt32Bytes53(populateIntegerMap(bytesProvider));
builder.putAllFieldMapInt32Double54(populateIntegerMap(doubleProvider));
builder.putAllFieldMapInt32Enum55(populateIntegerMap(enumProvider));
builder.putAllFieldMapInt32Fixed3256(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Fixed6457(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Float58(populateIntegerMap(floatProvider));
builder.putAllFieldMapInt32Int3259(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Int6460(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Message61(populateIntegerMap(messageProvider));
builder.putAllFieldMapInt32Sfixed3262(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Sfixed6463(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Sint3264(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Sint6465(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32String66(populateIntegerMap(stringProvider));
builder.putAllFieldMapInt32Uint3267(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Uint6468(populateIntegerMap(longProvider));
builder.putAllFieldMapInt64Bool69(populateLongMap(booleanProvider));
builder.putAllFieldMapInt64Bytes70(populateLongMap(bytesProvider));
builder.putAllFieldMapInt64Double71(populateLongMap(doubleProvider));
builder.putAllFieldMapInt64Enum72(populateLongMap(enumProvider));
builder.putAllFieldMapInt64Fixed3273(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Fixed6474(populateLongMap(longProvider));
builder.putAllFieldMapInt64Float75(populateLongMap(floatProvider));
builder.putAllFieldMapInt64Int3276(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Int6477(populateLongMap(longProvider));
builder.putAllFieldMapInt64Message78(populateLongMap(messageProvider));
builder.putAllFieldMapInt64Sfixed3279(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Sfixed6480(populateLongMap(longProvider));
builder.putAllFieldMapInt64Sint3281(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Sint6482(populateLongMap(longProvider));
builder.putAllFieldMapInt64String83(populateLongMap(stringProvider));
builder.putAllFieldMapInt64Uint3284(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Uint6485(populateLongMap(longProvider));
builder.putAllFieldMapSfixed32Bool86(populateIntegerMap(booleanProvider));
builder.putAllFieldMapSfixed32Bytes87(populateIntegerMap(bytesProvider));
builder.putAllFieldMapSfixed32Double88(populateIntegerMap(doubleProvider));
builder.putAllFieldMapSfixed32Enum89(populateIntegerMap(enumProvider));
builder.putAllFieldMapSfixed32Fixed3290(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Fixed6491(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Float92(populateIntegerMap(floatProvider));
builder.putAllFieldMapSfixed32Int3293(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Int6494(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Message95(populateIntegerMap(messageProvider));
builder.putAllFieldMapSfixed32Sfixed3296(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Sfixed6497(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Sint3298(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Sint6499(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32String100(populateIntegerMap(stringProvider));
builder.putAllFieldMapSfixed32Uint32101(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Uint64102(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed64Bool103(populateLongMap(booleanProvider));
builder.putAllFieldMapSfixed64Bytes104(populateLongMap(bytesProvider));
builder.putAllFieldMapSfixed64Double105(populateLongMap(doubleProvider));
builder.putAllFieldMapSfixed64Enum106(populateLongMap(enumProvider));
builder.putAllFieldMapSfixed64Fixed32107(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Fixed64108(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Float109(populateLongMap(floatProvider));
builder.putAllFieldMapSfixed64Int32110(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Int64111(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Message112(populateLongMap(messageProvider));
builder.putAllFieldMapSfixed64Sfixed32113(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Sfixed64114(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Sint32115(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Sint64116(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64String117(populateLongMap(stringProvider));
builder.putAllFieldMapSfixed64Uint32118(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Uint64119(populateLongMap(longProvider));
builder.putAllFieldMapSint32Bool120(populateIntegerMap(booleanProvider));
builder.putAllFieldMapSint32Bytes121(populateIntegerMap(bytesProvider));
builder.putAllFieldMapSint32Double122(populateIntegerMap(doubleProvider));
builder.putAllFieldMapSint32Enum123(populateIntegerMap(enumProvider));
builder.putAllFieldMapSint32Fixed32124(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Fixed64125(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Float126(populateIntegerMap(floatProvider));
builder.putAllFieldMapSint32Int32127(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Int64128(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Message129(populateIntegerMap(messageProvider));
builder.putAllFieldMapSint32Sfixed32130(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Sfixed64131(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Sint32132(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Sint64133(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32String134(populateIntegerMap(stringProvider));
builder.putAllFieldMapSint32Uint32135(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Uint64136(populateIntegerMap(longProvider));
builder.putAllFieldMapSint64Bool137(populateLongMap(booleanProvider));
builder.putAllFieldMapSint64Bytes138(populateLongMap(bytesProvider));
builder.putAllFieldMapSint64Double139(populateLongMap(doubleProvider));
builder.putAllFieldMapSint64Enum140(populateLongMap(enumProvider));
builder.putAllFieldMapSint64Fixed32141(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Fixed64142(populateLongMap(longProvider));
builder.putAllFieldMapSint64Float143(populateLongMap(floatProvider));
builder.putAllFieldMapSint64Int32144(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Int64145(populateLongMap(longProvider));
builder.putAllFieldMapSint64Message146(populateLongMap(messageProvider));
builder.putAllFieldMapSint64Sfixed32147(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Sfixed64148(populateLongMap(longProvider));
builder.putAllFieldMapSint64Sint32149(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Sint64150(populateLongMap(longProvider));
builder.putAllFieldMapSint64String151(populateLongMap(stringProvider));
builder.putAllFieldMapSint64Uint32152(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Uint64153(populateLongMap(longProvider));
builder.putAllFieldMapStringBool154(populateStringMap(booleanProvider));
builder.putAllFieldMapStringBytes155(populateStringMap(bytesProvider));
builder.putAllFieldMapStringDouble156(populateStringMap(doubleProvider));
builder.putAllFieldMapStringEnum157(populateStringMap(enumProvider));
builder.putAllFieldMapStringFixed32158(populateStringMap(integerProvider));
builder.putAllFieldMapStringFixed64159(populateStringMap(longProvider));
builder.putAllFieldMapStringFloat160(populateStringMap(floatProvider));
builder.putAllFieldMapStringInt32161(populateStringMap(integerProvider));
builder.putAllFieldMapStringInt64162(populateStringMap(longProvider));
builder.putAllFieldMapStringMessage163(populateStringMap(messageProvider));
builder.putAllFieldMapStringSfixed32164(populateStringMap(integerProvider));
builder.putAllFieldMapStringSfixed64165(populateStringMap(longProvider));
builder.putAllFieldMapStringSint32166(populateStringMap(integerProvider));
builder.putAllFieldMapStringSint64167(populateStringMap(longProvider));
builder.putAllFieldMapStringString168(populateStringMap(stringProvider));
builder.putAllFieldMapStringUint32169(populateStringMap(integerProvider));
builder.putAllFieldMapStringUint64170(populateStringMap(longProvider));
builder.putAllFieldMapUint32Bool171(populateIntegerMap(booleanProvider));
builder.putAllFieldMapUint32Bytes172(populateIntegerMap(bytesProvider));
builder.putAllFieldMapUint32Double173(populateIntegerMap(doubleProvider));
builder.putAllFieldMapUint32Enum174(populateIntegerMap(enumProvider));
builder.putAllFieldMapUint32Fixed32175(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Fixed64176(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Float177(populateIntegerMap(floatProvider));
builder.putAllFieldMapUint32Int32178(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Int64179(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Message180(populateIntegerMap(messageProvider));
builder.putAllFieldMapUint32Sfixed32181(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Sfixed64182(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Sint32183(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Sint64184(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32String185(populateIntegerMap(stringProvider));
builder.putAllFieldMapUint32Uint32186(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Uint64187(populateIntegerMap(longProvider));
builder.putAllFieldMapUint64Bool188(populateLongMap(booleanProvider));
builder.putAllFieldMapUint64Bytes189(populateLongMap(bytesProvider));
builder.putAllFieldMapUint64Double190(populateLongMap(doubleProvider));
builder.putAllFieldMapUint64Enum191(populateLongMap(enumProvider));
builder.putAllFieldMapUint64Fixed32192(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Fixed64193(populateLongMap(longProvider));
builder.putAllFieldMapUint64Float194(populateLongMap(floatProvider));
builder.putAllFieldMapUint64Int32195(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Int64196(populateLongMap(longProvider));
builder.putAllFieldMapUint64Message197(populateLongMap(messageProvider));
builder.putAllFieldMapUint64Sfixed32198(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Sfixed64199(populateLongMap(longProvider));
builder.putAllFieldMapUint64Sint32200(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Sint64201(populateLongMap(longProvider));
builder.putAllFieldMapUint64String202(populateLongMap(stringProvider));
builder.putAllFieldMapUint64Uint32203(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Uint64204(populateLongMap(longProvider));
return builder.build();
}
public List<Proto2Message> newMessagesMissingRequiredFields() {
List<Proto2Message> results = new ArrayList<>();
for (int i = 71; i <= 88; ++i) {
Proto2Message.Builder builder = Proto2Message.newBuilder();
populateRequiredFields(builder, i);
results.add(builder.buildPartial());
}
{
// A nested optional message field is missing required fields.
Proto2Message.Builder builder = Proto2Message.newBuilder();
populateRequiredFields(builder, INCLUDE_ALL_REQUIRED_FIELDS);
builder.setFieldMessage10(Proto2Message.getDefaultInstance());
results.add(builder.buildPartial());
}
{
// A nested repeated message field is missing required fields.
Proto2Message.Builder builder = Proto2Message.newBuilder();
populateRequiredFields(builder, INCLUDE_ALL_REQUIRED_FIELDS);
builder.addFieldMessageList27(Proto2Message.getDefaultInstance());
results.add(builder.buildPartial());
}
{
// A nested oneof message field is missing required fields.
Proto2Message.Builder builder = Proto2Message.newBuilder();
populateRequiredFields(builder, INCLUDE_ALL_REQUIRED_FIELDS);
builder.setFieldMessage62(Proto2Message.getDefaultInstance());
results.add(builder.buildPartial());
}
return results;
}
// 0 is not a valid field number so we use it to mean no fields are excluded.
private static final int INCLUDE_ALL_REQUIRED_FIELDS = 0;
private void populateRequiredFields(Proto2Message.Builder builder, int excludedFieldNumber) {
if (excludedFieldNumber != 71) {
builder.setFieldRequiredDouble71(data.getDouble());
}
if (excludedFieldNumber != 72) {
builder.setFieldRequiredFloat72(data.getFloat());
}
if (excludedFieldNumber != 73) {
builder.setFieldRequiredInt6473(data.getLong());
}
if (excludedFieldNumber != 74) {
builder.setFieldRequiredUint6474(data.getLong());
}
if (excludedFieldNumber != 75) {
builder.setFieldRequiredInt3275(data.getInt());
}
if (excludedFieldNumber != 76) {
builder.setFieldRequiredFixed6476(data.getLong());
}
if (excludedFieldNumber != 77) {
builder.setFieldRequiredFixed3277(data.getInt());
}
if (excludedFieldNumber != 78) {
builder.setFieldRequiredBool78(data.getBool());
}
if (excludedFieldNumber != 79) {
builder.setFieldRequiredString79(data.getString());
}
if (excludedFieldNumber != 80) {
builder.setFieldRequiredMessage80(
Proto2Message.RequiredNestedMessage.newBuilder().setValue(data.getInt()));
}
if (excludedFieldNumber != 81) {
builder.setFieldRequiredBytes81(data.getBytes());
}
if (excludedFieldNumber != 82) {
builder.setFieldRequiredUint3282(data.getInt());
}
if (excludedFieldNumber != 83) {
builder.setFieldRequiredEnum83(Proto2Message.TestEnum.forNumber(data.getEnum()));
}
if (excludedFieldNumber != 84) {
builder.setFieldRequiredSfixed3284(data.getInt());
}
if (excludedFieldNumber != 85) {
builder.setFieldRequiredSfixed6485(data.getLong());
}
if (excludedFieldNumber != 86) {
builder.setFieldRequiredSint3286(data.getInt());
}
if (excludedFieldNumber != 87) {
builder.setFieldRequiredSint6487(data.getLong());
}
if (excludedFieldNumber != 88) {
builder.setFieldRequiredGroup88(
Proto2Message.FieldRequiredGroup88.newBuilder().setFieldInt3289(data.getInt()));
}
}
}

View File

@ -0,0 +1,892 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.FieldInfo.forField;
import static com.google.protobuf.FieldInfo.forFieldWithEnumVerifier;
import static com.google.protobuf.FieldInfo.forMapField;
import static com.google.protobuf.FieldInfo.forOneofMemberField;
import static com.google.protobuf.FieldInfo.forProto2OptionalField;
import static com.google.protobuf.FieldInfo.forProto2RequiredField;
import static com.google.protobuf.FieldInfo.forRepeatedMessageField;
import com.google.protobuf.testing.Proto2Testing;
import com.google.protobuf.testing.Proto2Testing.Proto2Empty;
import com.google.protobuf.testing.Proto2Testing.Proto2Message;
import com.google.protobuf.testing.Proto2Testing.Proto2Message.FieldGroup49;
import com.google.protobuf.testing.Proto2Testing.Proto2Message.FieldGroup69;
import com.google.protobuf.testing.Proto2Testing.Proto2Message.FieldGroupList51;
import com.google.protobuf.testing.Proto2Testing.Proto2Message.FieldRequiredGroup88;
import com.google.protobuf.testing.Proto2Testing.Proto2Message.RequiredNestedMessage;
import com.google.protobuf.testing.Proto2Testing.Proto2Message.TestEnum;
import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithExtensions;
import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithMaps;
import java.lang.reflect.Field;
/** A factory that generates a hard-coded message info for {@link Proto2Message}. */
public final class Proto2MessageInfoFactory implements MessageInfoFactory {
private static final Proto2MessageInfoFactory INSTANCE = new Proto2MessageInfoFactory();
private Proto2MessageInfoFactory() {}
public static Proto2MessageInfoFactory getInstance() {
return INSTANCE;
}
@Override
public boolean isSupported(Class<?> clazz) {
return true;
}
@Override
public MessageInfo messageInfoFor(Class<?> clazz) {
if (Proto2Message.class.isAssignableFrom(clazz)) {
return newMessageInfoForProto2Message();
} else if (FieldGroup49.class.isAssignableFrom(clazz)) {
return newMessageInfoForFieldGroup49();
} else if (FieldGroupList51.class.isAssignableFrom(clazz)) {
return newMessageInfoForFieldGroupList51();
} else if (FieldGroup69.class.isAssignableFrom(clazz)) {
return newMessageInfoForFieldGroup69();
} else if (FieldRequiredGroup88.class.isAssignableFrom(clazz)) {
return newMessageInfoForFieldRequiredGroup88();
} else if (RequiredNestedMessage.class.isAssignableFrom(clazz)) {
return newMessageInfoForRequiredNestedMessage();
} else if (Proto2Empty.class.isAssignableFrom(clazz)) {
return newMessageInfoForProto2Empty();
} else if (Proto2MessageWithExtensions.class.isAssignableFrom(clazz)) {
return newMessageInfoForProto2MessageWithExtensions();
} else if (Proto2Testing.FieldGroup49.class.isAssignableFrom(clazz)) {
return newMessageInfoForExtensionFieldGroup49();
} else if (Proto2Testing.FieldGroupList51.class.isAssignableFrom(clazz)) {
return newMessageInfoForExtensionFieldGroupList51();
} else if (Proto2Testing.Proto2MessageWithMaps.class.isAssignableFrom(clazz)) {
return newMessageInfoForProto2MessageWithMaps();
} else {
throw new IllegalArgumentException("Unsupported class: " + clazz.getName());
}
}
/**
* Creates a new hard-coded info for {@link Proto2Message}. Each time this is called, we manually
* go through the entire process of what a message would do if it self-registered its own info,
* including looking up each field by name. This is done for benchmarking purposes, so that we get
* a more accurate representation of the time it takes to perform this process.
*/
private static StructuralMessageInfo newMessageInfoForProto2Message() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(50);
builder.withCheckInitialized(
new int[] {
10, 27, 62, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
});
lookupFieldsByName(builder);
return builder.build();
}
private static void lookupFieldsByName(StructuralMessageInfo.Builder builder) {
Field bitField0 = field("bitField0_");
builder.withDefaultInstance(Proto2Message.getDefaultInstance());
builder.withSyntax(ProtoSyntax.PROTO2);
builder.withField(
forProto2OptionalField(
field("fieldDouble1_"), 1, FieldType.DOUBLE, bitField0, 0x00000001, false, null));
builder.withField(
forProto2OptionalField(
field("fieldFloat2_"), 2, FieldType.FLOAT, bitField0, 0x00000002, false, null));
builder.withField(
forProto2OptionalField(
field("fieldInt643_"), 3, FieldType.INT64, bitField0, 0x00000004, false, null));
builder.withField(
forProto2OptionalField(
field("fieldUint644_"), 4, FieldType.UINT64, bitField0, 0x00000008, false, null));
builder.withField(
forProto2OptionalField(
field("fieldInt325_"), 5, FieldType.INT32, bitField0, 0x00000010, false, null));
builder.withField(
forProto2OptionalField(
field("fieldFixed646_"), 6, FieldType.FIXED64, bitField0, 0x00000020, false, null));
builder.withField(
forProto2OptionalField(
field("fieldFixed327_"), 7, FieldType.FIXED32, bitField0, 0x00000040, false, null));
builder.withField(
forProto2OptionalField(
field("fieldBool8_"), 8, FieldType.BOOL, bitField0, 0x00000080, false, null));
builder.withField(
forProto2OptionalField(
field("fieldString9_"), 9, FieldType.STRING, bitField0, 0x00000100, false, null));
builder.withField(
forProto2OptionalField(
field("fieldMessage10_"), 10, FieldType.MESSAGE, bitField0, 0x00000200, false, null));
builder.withField(
forProto2OptionalField(
field("fieldBytes11_"), 11, FieldType.BYTES, bitField0, 0x00000400, false, null));
builder.withField(
forProto2OptionalField(
field("fieldUint3212_"), 12, FieldType.UINT32, bitField0, 0x00000800, false, null));
builder.withField(
forProto2OptionalField(
field("fieldEnum13_"),
13,
FieldType.ENUM,
bitField0,
0x00001000,
false,
asVerifier(TestEnum.internalGetValueMap())));
builder.withField(
forProto2OptionalField(
field("fieldSfixed3214_"), 14, FieldType.SFIXED32, bitField0, 0x00002000, false, null));
builder.withField(
forProto2OptionalField(
field("fieldSfixed6415_"), 15, FieldType.SFIXED64, bitField0, 0x00004000, false, null));
builder.withField(
forProto2OptionalField(
field("fieldSint3216_"), 16, FieldType.SINT32, bitField0, 0x00008000, false, null));
builder.withField(
forProto2OptionalField(
field("fieldSint6417_"), 17, FieldType.SINT64, bitField0, 0x00010000, false, null));
builder.withField(forField(field("fieldDoubleList18_"), 18, FieldType.DOUBLE_LIST, false));
builder.withField(forField(field("fieldFloatList19_"), 19, FieldType.FLOAT_LIST, false));
builder.withField(forField(field("fieldInt64List20_"), 20, FieldType.INT64_LIST, false));
builder.withField(forField(field("fieldUint64List21_"), 21, FieldType.UINT64_LIST, false));
builder.withField(forField(field("fieldInt32List22_"), 22, FieldType.INT32_LIST, false));
builder.withField(forField(field("fieldFixed64List23_"), 23, FieldType.FIXED64_LIST, false));
builder.withField(forField(field("fieldFixed32List24_"), 24, FieldType.FIXED32_LIST, false));
builder.withField(forField(field("fieldBoolList25_"), 25, FieldType.BOOL_LIST, false));
builder.withField(forField(field("fieldStringList26_"), 26, FieldType.STRING_LIST, false));
builder.withField(
forRepeatedMessageField(
field("fieldMessageList27_"), 27, FieldType.MESSAGE_LIST, Proto2Message.class));
builder.withField(forField(field("fieldBytesList28_"), 28, FieldType.BYTES_LIST, false));
builder.withField(forField(field("fieldUint32List29_"), 29, FieldType.UINT32_LIST, false));
builder.withField(
forFieldWithEnumVerifier(
field("fieldEnumList30_"),
30,
FieldType.ENUM_LIST,
asVerifier(TestEnum.internalGetValueMap())));
builder.withField(forField(field("fieldSfixed32List31_"), 31, FieldType.SFIXED32_LIST, false));
builder.withField(forField(field("fieldSfixed64List32_"), 32, FieldType.SFIXED64_LIST, false));
builder.withField(forField(field("fieldSint32List33_"), 33, FieldType.SINT32_LIST, false));
builder.withField(forField(field("fieldSint64List34_"), 34, FieldType.SINT64_LIST, false));
builder.withField(
forField(field("fieldDoubleListPacked35_"), 35, FieldType.DOUBLE_LIST_PACKED, false));
builder.withField(
forField(field("fieldFloatListPacked36_"), 36, FieldType.FLOAT_LIST_PACKED, false));
builder.withField(
forField(field("fieldInt64ListPacked37_"), 37, FieldType.INT64_LIST_PACKED, false));
builder.withField(
forField(field("fieldUint64ListPacked38_"), 38, FieldType.UINT64_LIST_PACKED, false));
builder.withField(
forField(field("fieldInt32ListPacked39_"), 39, FieldType.INT32_LIST_PACKED, false));
builder.withField(
forField(field("fieldFixed64ListPacked40_"), 40, FieldType.FIXED64_LIST_PACKED, false));
builder.withField(
forField(field("fieldFixed32ListPacked41_"), 41, FieldType.FIXED32_LIST_PACKED, false));
builder.withField(
forField(field("fieldBoolListPacked42_"), 42, FieldType.BOOL_LIST_PACKED, false));
builder.withField(
forField(field("fieldUint32ListPacked43_"), 43, FieldType.UINT32_LIST_PACKED, false));
builder.withField(
forFieldWithEnumVerifier(
field("fieldEnumListPacked44_"),
44,
FieldType.ENUM_LIST_PACKED,
asVerifier(TestEnum.internalGetValueMap())));
builder.withField(
forField(field("fieldSfixed32ListPacked45_"), 45, FieldType.SFIXED32_LIST_PACKED, false));
builder.withField(
forField(field("fieldSfixed64ListPacked46_"), 46, FieldType.SFIXED64_LIST_PACKED, false));
builder.withField(
forField(field("fieldSint32ListPacked47_"), 47, FieldType.SINT32_LIST_PACKED, false));
builder.withField(
forField(field("fieldSint64ListPacked48_"), 48, FieldType.SINT64_LIST_PACKED, false));
builder.withField(
forProto2OptionalField(
field("fieldGroup49_"), 49, FieldType.GROUP, bitField0, 0x00020000, false, null));
builder.withField(
forRepeatedMessageField(
field("fieldGroupList51_"),
51,
FieldType.GROUP_LIST,
Proto2Message.FieldGroupList51.class));
OneofInfo oneof = new OneofInfo(0, field("testOneofCase_"), field("testOneof_"));
builder.withField(forOneofMemberField(53, FieldType.DOUBLE, oneof, Double.class, false, null));
builder.withField(forOneofMemberField(54, FieldType.FLOAT, oneof, Float.class, false, null));
builder.withField(forOneofMemberField(55, FieldType.INT64, oneof, Long.class, false, null));
builder.withField(forOneofMemberField(56, FieldType.UINT64, oneof, Long.class, false, null));
builder.withField(forOneofMemberField(57, FieldType.INT32, oneof, Integer.class, false, null));
builder.withField(forOneofMemberField(58, FieldType.FIXED64, oneof, Long.class, false, null));
builder.withField(
forOneofMemberField(59, FieldType.FIXED32, oneof, Integer.class, false, null));
builder.withField(forOneofMemberField(60, FieldType.BOOL, oneof, Boolean.class, false, null));
builder.withField(forOneofMemberField(61, FieldType.STRING, oneof, String.class, false, null));
builder.withField(
forOneofMemberField(62, FieldType.MESSAGE, oneof, Proto2Message.class, false, null));
builder.withField(
forOneofMemberField(63, FieldType.BYTES, oneof, ByteString.class, false, null));
builder.withField(forOneofMemberField(64, FieldType.UINT32, oneof, Integer.class, false, null));
builder.withField(
forOneofMemberField(65, FieldType.SFIXED32, oneof, Integer.class, false, null));
builder.withField(forOneofMemberField(66, FieldType.SFIXED64, oneof, Long.class, false, null));
builder.withField(forOneofMemberField(67, FieldType.SINT32, oneof, Integer.class, false, null));
builder.withField(forOneofMemberField(68, FieldType.SINT64, oneof, Long.class, false, null));
builder.withField(
forOneofMemberField(
69, FieldType.GROUP, oneof, Proto2Message.FieldGroup69.class, false, null));
Field bitField1 = field("bitField1_");
builder.withField(
forProto2RequiredField(
field("fieldRequiredDouble71_"),
71,
FieldType.DOUBLE,
bitField1,
0x00000008,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredFloat72_"),
72,
FieldType.FLOAT,
bitField1,
0x00000010,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredInt6473_"),
73,
FieldType.INT64,
bitField1,
0x00000020,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredUint6474_"),
74,
FieldType.UINT64,
bitField1,
0x00000040,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredInt3275_"),
75,
FieldType.INT32,
bitField1,
0x00000080,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredFixed6476_"),
76,
FieldType.FIXED64,
bitField1,
0x00000100,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredFixed3277_"),
77,
FieldType.FIXED32,
bitField1,
0x00000200,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredBool78_"), 78, FieldType.BOOL, bitField1, 0x00000400, false, null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredString79_"),
79,
FieldType.STRING,
bitField1,
0x00000800,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredMessage80_"),
80,
FieldType.MESSAGE,
bitField1,
0x00001000,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredBytes81_"),
81,
FieldType.BYTES,
bitField1,
0x00002000,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredUint3282_"),
82,
FieldType.UINT32,
bitField1,
0x00004000,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredEnum83_"),
83,
FieldType.ENUM,
bitField1,
0x00008000,
false,
asVerifier(TestEnum.internalGetValueMap())));
builder.withField(
forProto2RequiredField(
field("fieldRequiredSfixed3284_"),
84,
FieldType.SFIXED32,
bitField1,
0x00010000,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredSfixed6485_"),
85,
FieldType.SFIXED64,
bitField1,
0x00020000,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredSint3286_"),
86,
FieldType.SINT32,
bitField1,
0x00040000,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredSint6487_"),
87,
FieldType.SINT64,
bitField1,
0x00080000,
false,
null));
builder.withField(
forProto2RequiredField(
field("fieldRequiredGroup88_"),
88,
FieldType.GROUP,
bitField1,
0x00100000,
false,
null));
}
private static StructuralMessageInfo newMessageInfoForFieldGroup49() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO2);
Field bitField0 = field(FieldGroup49.class, "bitField0_");
builder.withField(
forProto2OptionalField(
field(FieldGroup49.class, "fieldInt3250_"),
50,
FieldType.INT32,
bitField0,
0x00000001,
false,
null));
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForFieldGroupList51() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO2);
Field bitField0 = field(FieldGroupList51.class, "bitField0_");
builder.withField(
forProto2OptionalField(
field(FieldGroupList51.class, "fieldInt3252_"),
52,
FieldType.INT32,
bitField0,
0x00000001,
false,
null));
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForFieldGroup69() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO2);
Field bitField0 = field(FieldGroup69.class, "bitField0_");
builder.withField(
forProto2OptionalField(
field(FieldGroup69.class, "fieldInt3270_"),
70,
FieldType.INT32,
bitField0,
0x00000001,
false,
null));
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForRequiredNestedMessage() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO2);
Field bitField0 = field(RequiredNestedMessage.class, "bitField0_");
builder.withField(
forProto2OptionalField(
field(RequiredNestedMessage.class, "value_"),
1,
FieldType.INT32,
bitField0,
0x00000001,
false,
null));
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForFieldRequiredGroup88() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO2);
Field bitField0 = field(FieldRequiredGroup88.class, "bitField0_");
builder.withField(
forProto2OptionalField(
field(FieldRequiredGroup88.class, "fieldInt3289_"),
89,
FieldType.INT32,
bitField0,
0x00000001,
false,
null));
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForProto2Empty() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO2);
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForProto2MessageWithExtensions() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(0);
builder.withSyntax(ProtoSyntax.PROTO2);
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForExtensionFieldGroup49() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO2);
Field bitField0 = field(Proto2Testing.FieldGroup49.class, "bitField0_");
builder.withField(
forProto2OptionalField(
field(Proto2Testing.FieldGroup49.class, "fieldInt3250_"),
50,
FieldType.INT32,
bitField0,
0x00000001,
false,
null));
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForExtensionFieldGroupList51() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO2);
Field bitField0 = field(Proto2Testing.FieldGroupList51.class, "bitField0_");
builder.withField(
forProto2OptionalField(
field(Proto2Testing.FieldGroupList51.class, "fieldInt3252_"),
52,
FieldType.INT32,
bitField0,
0x00000001,
false,
null));
return builder.build();
}
private static StructuralMessageInfo newMessageInfoForProto2MessageWithMaps() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder();
builder.withCheckInitialized(
new int[] {
10, 27, 44, 61, 78, 95, 112, 129, 146, 163, 180, 197,
});
builder.withSyntax(ProtoSyntax.PROTO2);
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_bool_1", 1));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_bytes_2", 2));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_double_3", 3));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_enum_4", 4));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_fixed32_5", 5));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_fixed64_6", 6));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_float_7", 7));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_int32_8", 8));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_int64_9", 9));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_message_10", 10));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_sfixed32_11", 11));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_sfixed64_12", 12));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_sint32_13", 13));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_sint64_14", 14));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_string_15", 15));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_uint32_16", 16));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_bool_uint64_17", 17));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_bool_18", 18));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_bytes_19", 19));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_double_20", 20));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_enum_21", 21));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_fixed32_22", 22));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_fixed64_23", 23));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_float_24", 24));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_int32_25", 25));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_int64_26", 26));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_message_27", 27));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_sfixed32_28", 28));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_sfixed64_29", 29));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_sint32_30", 30));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_sint64_31", 31));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_string_32", 32));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_uint32_33", 33));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed32_uint64_34", 34));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_bool_35", 35));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_bytes_36", 36));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_double_37", 37));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_enum_38", 38));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_fixed32_39", 39));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_fixed64_40", 40));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_float_41", 41));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_int32_42", 42));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_int64_43", 43));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_message_44", 44));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_sfixed32_45", 45));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_sfixed64_46", 46));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_sint32_47", 47));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_sint64_48", 48));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_string_49", 49));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_uint32_50", 50));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_fixed64_uint64_51", 51));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_bool_52", 52));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_bytes_53", 53));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_double_54", 54));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_enum_55", 55));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_fixed32_56", 56));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_fixed64_57", 57));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_float_58", 58));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_int32_59", 59));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_int64_60", 60));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_message_61", 61));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_sfixed32_62", 62));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_sfixed64_63", 63));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_sint32_64", 64));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_sint64_65", 65));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_string_66", 66));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_uint32_67", 67));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int32_uint64_68", 68));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_bool_69", 69));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_bytes_70", 70));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_double_71", 71));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_enum_72", 72));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_fixed32_73", 73));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_fixed64_74", 74));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_float_75", 75));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_int32_76", 76));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_int64_77", 77));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_message_78", 78));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_sfixed32_79", 79));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_sfixed64_80", 80));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_sint32_81", 81));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_sint64_82", 82));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_string_83", 83));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_uint32_84", 84));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_int64_uint64_85", 85));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_bool_86", 86));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_bytes_87", 87));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_double_88", 88));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_enum_89", 89));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_fixed32_90", 90));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_fixed64_91", 91));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_float_92", 92));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_int32_93", 93));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_int64_94", 94));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_message_95", 95));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_sfixed32_96", 96));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_sfixed64_97", 97));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_sint32_98", 98));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_sint64_99", 99));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_string_100", 100));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_uint32_101", 101));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed32_uint64_102", 102));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_bool_103", 103));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_bytes_104", 104));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_double_105", 105));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_enum_106", 106));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_fixed32_107", 107));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_fixed64_108", 108));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_float_109", 109));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_int32_110", 110));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_int64_111", 111));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_message_112", 112));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_sfixed32_113", 113));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_sfixed64_114", 114));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_sint32_115", 115));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_sint64_116", 116));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_string_117", 117));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_uint32_118", 118));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sfixed64_uint64_119", 119));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_bool_120", 120));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_bytes_121", 121));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_double_122", 122));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_enum_123", 123));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_fixed32_124", 124));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_fixed64_125", 125));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_float_126", 126));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_int32_127", 127));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_int64_128", 128));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_message_129", 129));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_sfixed32_130", 130));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_sfixed64_131", 131));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_sint32_132", 132));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_sint64_133", 133));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_string_134", 134));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_uint32_135", 135));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint32_uint64_136", 136));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_bool_137", 137));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_bytes_138", 138));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_double_139", 139));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_enum_140", 140));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_fixed32_141", 141));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_fixed64_142", 142));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_float_143", 143));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_int32_144", 144));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_int64_145", 145));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_message_146", 146));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_sfixed32_147", 147));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_sfixed64_148", 148));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_sint32_149", 149));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_sint64_150", 150));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_string_151", 151));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_uint32_152", 152));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_sint64_uint64_153", 153));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_bool_154", 154));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_bytes_155", 155));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_double_156", 156));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_enum_157", 157));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_fixed32_158", 158));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_fixed64_159", 159));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_float_160", 160));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_int32_161", 161));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_int64_162", 162));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_message_163", 163));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_sfixed32_164", 164));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_sfixed64_165", 165));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_sint32_166", 166));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_sint64_167", 167));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_string_168", 168));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_uint32_169", 169));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_string_uint64_170", 170));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_bool_171", 171));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_bytes_172", 172));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_double_173", 173));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_enum_174", 174));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_fixed32_175", 175));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_fixed64_176", 176));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_float_177", 177));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_int32_178", 178));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_int64_179", 179));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_message_180", 180));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_sfixed32_181", 181));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_sfixed64_182", 182));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_sint32_183", 183));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_sint64_184", 184));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_string_185", 185));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_uint32_186", 186));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint32_uint64_187", 187));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_bool_188", 188));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_bytes_189", 189));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_double_190", 190));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_enum_191", 191));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_fixed32_192", 192));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_fixed64_193", 193));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_float_194", 194));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_int32_195", 195));
builder.withField(mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_int64_196", 196));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_message_197", 197));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_sfixed32_198", 198));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_sfixed64_199", 199));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_sint32_200", 200));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_sint64_201", 201));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_string_202", 202));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_uint32_203", 203));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_uint64_204", 204));
return builder.build();
}
private static FieldInfo mapFieldInfo(Class<?> clazz, String fieldName, int fieldNumber) {
try {
return forMapField(
field(clazz, SchemaUtil.toCamelCase(fieldName, false) + "_"),
fieldNumber,
SchemaUtil.getMapDefaultEntry(clazz, fieldName),
fieldName.contains("_enum_") ? asVerifier(TestEnum.internalGetValueMap()) : null);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
private static Field field(String name) {
return field(Proto2Message.class, name);
}
private static Field field(Class<?> clazz, String name) {
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException | SecurityException e) {
throw new RuntimeException(e);
}
}
private static Internal.EnumVerifier asVerifier(final Internal.EnumLiteMap<?> map) {
return new Internal.EnumVerifier() {
@Override
public boolean isInRange(int number) {
return map.findValueByNumber(number) != null;
}
};
}
}

View File

@ -0,0 +1,558 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLite;
import com.google.protobuf.testing.Proto2TestingLite.Proto2MessageLiteWithMaps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/** Creates instances of {@link Proto2MessageLite} based on the tree configuration. */
public final class Proto2MessageLiteFactory
implements ExperimentalMessageFactory<Proto2MessageLite> {
private final int numRepeatedFields;
private final int branchingFactor;
private final Proto2MessageLiteFactory nextLevel;
private final ExperimentalTestDataProvider data;
public Proto2MessageLiteFactory(
int numRepeatedFields, int stringLength, int branchingFactor, int treeDepth) {
this(
new ExperimentalTestDataProvider(stringLength),
numRepeatedFields,
branchingFactor,
treeDepth);
}
private Proto2MessageLiteFactory(
ExperimentalTestDataProvider data,
int numRepeatedFields,
int branchingFactor,
int treeDepth) {
this.numRepeatedFields = numRepeatedFields;
this.branchingFactor = branchingFactor;
this.data = data;
if (treeDepth > 0) {
nextLevel =
new Proto2MessageLiteFactory(data, numRepeatedFields, branchingFactor, treeDepth - 1);
} else {
nextLevel = null;
}
}
@Override
public ExperimentalTestDataProvider dataProvider() {
return data;
}
@Override
public Proto2MessageLite newMessage() {
Proto2MessageLite.Builder builder = Proto2MessageLite.newBuilder();
builder.setFieldDouble1(data.getDouble());
builder.setFieldFloat2(data.getFloat());
builder.setFieldInt643(data.getLong());
builder.setFieldUint644(data.getLong());
builder.setFieldInt325(data.getInt());
builder.setFieldFixed646(data.getLong());
builder.setFieldFixed327(data.getInt());
builder.setFieldBool8(data.getBool());
builder.setFieldString9(data.getString());
// We don't populate the message field. Instead we apply the branching factor to the
// repeated message field below.
builder.setFieldBytes11(data.getBytes());
builder.setFieldUint3212(data.getInt());
builder.setFieldEnum13(Proto2MessageLite.TestEnum.forNumber(data.getEnum()));
builder.setFieldSfixed3214(data.getInt());
builder.setFieldSfixed6415(data.getLong());
builder.setFieldSint3216(data.getInt());
builder.setFieldSint6417(data.getLong());
for (int i = 0; i < numRepeatedFields; ++i) {
builder.addFieldDoubleList18(data.getDouble());
builder.addFieldFloatList19(data.getFloat());
builder.addFieldInt64List20(data.getLong());
builder.addFieldUint64List21(data.getLong());
builder.addFieldInt32List22(data.getInt());
builder.addFieldFixed64List23(data.getLong());
builder.addFieldFixed32List24(data.getInt());
builder.addFieldBoolList25(data.getBool());
builder.addFieldStringList26(data.getString());
// Repeated message field is controlled by the branching factor below.
builder.addFieldBytesList28(data.getBytes());
builder.addFieldUint32List29(data.getInt());
builder.addFieldEnumList30(Proto2MessageLite.TestEnum.forNumber(data.getEnum()));
builder.addFieldSfixed32List31(data.getInt());
builder.addFieldSfixed64List32(data.getLong());
builder.addFieldSint32List33(data.getInt());
builder.addFieldSint64List34(data.getLong());
builder.addFieldDoubleListPacked35(data.getDouble());
builder.addFieldFloatListPacked36(data.getFloat());
builder.addFieldInt64ListPacked37(data.getLong());
builder.addFieldUint64ListPacked38(data.getLong());
builder.addFieldInt32ListPacked39(data.getInt());
builder.addFieldFixed64ListPacked40(data.getLong());
builder.addFieldFixed32ListPacked41(data.getInt());
builder.addFieldBoolListPacked42(data.getBool());
builder.addFieldUint32ListPacked43(data.getInt());
builder.addFieldEnumListPacked44(Proto2MessageLite.TestEnum.forNumber(data.getEnum()));
builder.addFieldSfixed32ListPacked45(data.getInt());
builder.addFieldSfixed64ListPacked46(data.getLong());
builder.addFieldSint32ListPacked47(data.getInt());
builder.addFieldSint64ListPacked48(data.getLong());
}
builder.setFieldGroup49(
Proto2MessageLite.FieldGroup49.newBuilder().setFieldInt3250(data.getInt()));
for (int i = 0; i < branchingFactor; ++i) {
builder.addFieldGroupList51(
Proto2MessageLite.FieldGroupList51.newBuilder().setFieldInt3252(data.getInt()));
}
// Set all required fields.
populateRequiredFields(builder, INCLUDE_ALL_REQUIRED_FIELDS);
// Handle the branching factor.
if (nextLevel != null) {
for (int i = 0; i < branchingFactor; ++i) {
builder.addFieldMessageList27(nextLevel.newMessage());
}
}
return builder.build();
}
private interface MapValueProvider<T> {
public T getValue();
}
private final MapValueProvider<Integer> integerProvider =
new MapValueProvider<Integer>() {
@Override
public Integer getValue() {
return data.getInt();
}
};
private final MapValueProvider<Long> longProvider =
new MapValueProvider<Long>() {
@Override
public Long getValue() {
return data.getLong();
}
};
private final MapValueProvider<String> stringProvider =
new MapValueProvider<String>() {
@Override
public String getValue() {
return data.getString();
}
};
private final MapValueProvider<ByteString> bytesProvider =
new MapValueProvider<ByteString>() {
@Override
public ByteString getValue() {
return data.getBytes();
}
};
private final MapValueProvider<Boolean> booleanProvider =
new MapValueProvider<Boolean>() {
@Override
public Boolean getValue() {
return data.getBool();
}
};
private final MapValueProvider<Float> floatProvider =
new MapValueProvider<Float>() {
@Override
public Float getValue() {
return data.getFloat();
}
};
private final MapValueProvider<Double> doubleProvider =
new MapValueProvider<Double>() {
@Override
public Double getValue() {
return data.getDouble();
}
};
private final MapValueProvider<Proto2MessageLite> messageProvider =
new MapValueProvider<Proto2MessageLite>() {
@Override
public Proto2MessageLite getValue() {
return newMessage();
}
};
private final MapValueProvider<Proto2MessageLite.TestEnum> enumProvider =
new MapValueProvider<Proto2MessageLite.TestEnum>() {
@Override
public Proto2MessageLite.TestEnum getValue() {
return Proto2MessageLite.TestEnum.forNumber(data.getEnum());
}
};
private <V> Map<Integer, V> populateIntegerMap(MapValueProvider<V> provider) {
Map<Integer, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getInt(), provider.getValue());
}
return map;
}
private <V> Map<Long, V> populateLongMap(MapValueProvider<V> provider) {
Map<Long, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getLong(), provider.getValue());
}
return map;
}
private <V> Map<String, V> populateStringMap(MapValueProvider<V> provider) {
Map<String, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getString(), provider.getValue());
}
return map;
}
private <V> Map<Boolean, V> populateBooleanMap(MapValueProvider<V> provider) {
Map<Boolean, V> map = new HashMap<>();
map.put(false, provider.getValue());
map.put(true, provider.getValue());
return map;
}
public Proto2MessageLiteWithMaps newMessageWithMaps() {
Proto2MessageLiteWithMaps.Builder builder = Proto2MessageLiteWithMaps.newBuilder();
builder.putAllFieldMapBoolBool1(populateBooleanMap(booleanProvider));
builder.putAllFieldMapBoolBytes2(populateBooleanMap(bytesProvider));
builder.putAllFieldMapBoolDouble3(populateBooleanMap(doubleProvider));
builder.putAllFieldMapBoolEnum4(populateBooleanMap(enumProvider));
builder.putAllFieldMapBoolFixed325(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolFixed646(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolFloat7(populateBooleanMap(floatProvider));
builder.putAllFieldMapBoolInt328(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolInt649(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolMessage10(populateBooleanMap(messageProvider));
builder.putAllFieldMapBoolSfixed3211(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolSfixed6412(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolSint3213(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolSint6414(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolString15(populateBooleanMap(stringProvider));
builder.putAllFieldMapBoolUint3216(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolUint6417(populateBooleanMap(longProvider));
builder.putAllFieldMapFixed32Bool18(populateIntegerMap(booleanProvider));
builder.putAllFieldMapFixed32Bytes19(populateIntegerMap(bytesProvider));
builder.putAllFieldMapFixed32Double20(populateIntegerMap(doubleProvider));
builder.putAllFieldMapFixed32Enum21(populateIntegerMap(enumProvider));
builder.putAllFieldMapFixed32Fixed3222(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Fixed6423(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Float24(populateIntegerMap(floatProvider));
builder.putAllFieldMapFixed32Int3225(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Int6426(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Message27(populateIntegerMap(messageProvider));
builder.putAllFieldMapFixed32Sfixed3228(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Sfixed6429(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Sint3230(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Sint6431(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32String32(populateIntegerMap(stringProvider));
builder.putAllFieldMapFixed32Uint3233(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Uint6434(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed64Bool35(populateLongMap(booleanProvider));
builder.putAllFieldMapFixed64Bytes36(populateLongMap(bytesProvider));
builder.putAllFieldMapFixed64Double37(populateLongMap(doubleProvider));
builder.putAllFieldMapFixed64Enum38(populateLongMap(enumProvider));
builder.putAllFieldMapFixed64Fixed3239(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Fixed6440(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Float41(populateLongMap(floatProvider));
builder.putAllFieldMapFixed64Int3242(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Int6443(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Message44(populateLongMap(messageProvider));
builder.putAllFieldMapFixed64Sfixed3245(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Sfixed6446(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Sint3247(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Sint6448(populateLongMap(longProvider));
builder.putAllFieldMapFixed64String49(populateLongMap(stringProvider));
builder.putAllFieldMapFixed64Uint3250(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Uint6451(populateLongMap(longProvider));
builder.putAllFieldMapInt32Bool52(populateIntegerMap(booleanProvider));
builder.putAllFieldMapInt32Bytes53(populateIntegerMap(bytesProvider));
builder.putAllFieldMapInt32Double54(populateIntegerMap(doubleProvider));
builder.putAllFieldMapInt32Enum55(populateIntegerMap(enumProvider));
builder.putAllFieldMapInt32Fixed3256(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Fixed6457(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Float58(populateIntegerMap(floatProvider));
builder.putAllFieldMapInt32Int3259(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Int6460(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Message61(populateIntegerMap(messageProvider));
builder.putAllFieldMapInt32Sfixed3262(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Sfixed6463(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Sint3264(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Sint6465(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32String66(populateIntegerMap(stringProvider));
builder.putAllFieldMapInt32Uint3267(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Uint6468(populateIntegerMap(longProvider));
builder.putAllFieldMapInt64Bool69(populateLongMap(booleanProvider));
builder.putAllFieldMapInt64Bytes70(populateLongMap(bytesProvider));
builder.putAllFieldMapInt64Double71(populateLongMap(doubleProvider));
builder.putAllFieldMapInt64Enum72(populateLongMap(enumProvider));
builder.putAllFieldMapInt64Fixed3273(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Fixed6474(populateLongMap(longProvider));
builder.putAllFieldMapInt64Float75(populateLongMap(floatProvider));
builder.putAllFieldMapInt64Int3276(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Int6477(populateLongMap(longProvider));
builder.putAllFieldMapInt64Message78(populateLongMap(messageProvider));
builder.putAllFieldMapInt64Sfixed3279(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Sfixed6480(populateLongMap(longProvider));
builder.putAllFieldMapInt64Sint3281(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Sint6482(populateLongMap(longProvider));
builder.putAllFieldMapInt64String83(populateLongMap(stringProvider));
builder.putAllFieldMapInt64Uint3284(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Uint6485(populateLongMap(longProvider));
builder.putAllFieldMapSfixed32Bool86(populateIntegerMap(booleanProvider));
builder.putAllFieldMapSfixed32Bytes87(populateIntegerMap(bytesProvider));
builder.putAllFieldMapSfixed32Double88(populateIntegerMap(doubleProvider));
builder.putAllFieldMapSfixed32Enum89(populateIntegerMap(enumProvider));
builder.putAllFieldMapSfixed32Fixed3290(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Fixed6491(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Float92(populateIntegerMap(floatProvider));
builder.putAllFieldMapSfixed32Int3293(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Int6494(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Message95(populateIntegerMap(messageProvider));
builder.putAllFieldMapSfixed32Sfixed3296(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Sfixed6497(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Sint3298(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Sint6499(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32String100(populateIntegerMap(stringProvider));
builder.putAllFieldMapSfixed32Uint32101(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Uint64102(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed64Bool103(populateLongMap(booleanProvider));
builder.putAllFieldMapSfixed64Bytes104(populateLongMap(bytesProvider));
builder.putAllFieldMapSfixed64Double105(populateLongMap(doubleProvider));
builder.putAllFieldMapSfixed64Enum106(populateLongMap(enumProvider));
builder.putAllFieldMapSfixed64Fixed32107(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Fixed64108(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Float109(populateLongMap(floatProvider));
builder.putAllFieldMapSfixed64Int32110(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Int64111(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Message112(populateLongMap(messageProvider));
builder.putAllFieldMapSfixed64Sfixed32113(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Sfixed64114(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Sint32115(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Sint64116(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64String117(populateLongMap(stringProvider));
builder.putAllFieldMapSfixed64Uint32118(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Uint64119(populateLongMap(longProvider));
builder.putAllFieldMapSint32Bool120(populateIntegerMap(booleanProvider));
builder.putAllFieldMapSint32Bytes121(populateIntegerMap(bytesProvider));
builder.putAllFieldMapSint32Double122(populateIntegerMap(doubleProvider));
builder.putAllFieldMapSint32Enum123(populateIntegerMap(enumProvider));
builder.putAllFieldMapSint32Fixed32124(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Fixed64125(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Float126(populateIntegerMap(floatProvider));
builder.putAllFieldMapSint32Int32127(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Int64128(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Message129(populateIntegerMap(messageProvider));
builder.putAllFieldMapSint32Sfixed32130(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Sfixed64131(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Sint32132(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Sint64133(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32String134(populateIntegerMap(stringProvider));
builder.putAllFieldMapSint32Uint32135(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Uint64136(populateIntegerMap(longProvider));
builder.putAllFieldMapSint64Bool137(populateLongMap(booleanProvider));
builder.putAllFieldMapSint64Bytes138(populateLongMap(bytesProvider));
builder.putAllFieldMapSint64Double139(populateLongMap(doubleProvider));
builder.putAllFieldMapSint64Enum140(populateLongMap(enumProvider));
builder.putAllFieldMapSint64Fixed32141(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Fixed64142(populateLongMap(longProvider));
builder.putAllFieldMapSint64Float143(populateLongMap(floatProvider));
builder.putAllFieldMapSint64Int32144(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Int64145(populateLongMap(longProvider));
builder.putAllFieldMapSint64Message146(populateLongMap(messageProvider));
builder.putAllFieldMapSint64Sfixed32147(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Sfixed64148(populateLongMap(longProvider));
builder.putAllFieldMapSint64Sint32149(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Sint64150(populateLongMap(longProvider));
builder.putAllFieldMapSint64String151(populateLongMap(stringProvider));
builder.putAllFieldMapSint64Uint32152(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Uint64153(populateLongMap(longProvider));
builder.putAllFieldMapStringBool154(populateStringMap(booleanProvider));
builder.putAllFieldMapStringBytes155(populateStringMap(bytesProvider));
builder.putAllFieldMapStringDouble156(populateStringMap(doubleProvider));
builder.putAllFieldMapStringEnum157(populateStringMap(enumProvider));
builder.putAllFieldMapStringFixed32158(populateStringMap(integerProvider));
builder.putAllFieldMapStringFixed64159(populateStringMap(longProvider));
builder.putAllFieldMapStringFloat160(populateStringMap(floatProvider));
builder.putAllFieldMapStringInt32161(populateStringMap(integerProvider));
builder.putAllFieldMapStringInt64162(populateStringMap(longProvider));
builder.putAllFieldMapStringMessage163(populateStringMap(messageProvider));
builder.putAllFieldMapStringSfixed32164(populateStringMap(integerProvider));
builder.putAllFieldMapStringSfixed64165(populateStringMap(longProvider));
builder.putAllFieldMapStringSint32166(populateStringMap(integerProvider));
builder.putAllFieldMapStringSint64167(populateStringMap(longProvider));
builder.putAllFieldMapStringString168(populateStringMap(stringProvider));
builder.putAllFieldMapStringUint32169(populateStringMap(integerProvider));
builder.putAllFieldMapStringUint64170(populateStringMap(longProvider));
builder.putAllFieldMapUint32Bool171(populateIntegerMap(booleanProvider));
builder.putAllFieldMapUint32Bytes172(populateIntegerMap(bytesProvider));
builder.putAllFieldMapUint32Double173(populateIntegerMap(doubleProvider));
builder.putAllFieldMapUint32Enum174(populateIntegerMap(enumProvider));
builder.putAllFieldMapUint32Fixed32175(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Fixed64176(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Float177(populateIntegerMap(floatProvider));
builder.putAllFieldMapUint32Int32178(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Int64179(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Message180(populateIntegerMap(messageProvider));
builder.putAllFieldMapUint32Sfixed32181(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Sfixed64182(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Sint32183(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Sint64184(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32String185(populateIntegerMap(stringProvider));
builder.putAllFieldMapUint32Uint32186(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Uint64187(populateIntegerMap(longProvider));
builder.putAllFieldMapUint64Bool188(populateLongMap(booleanProvider));
builder.putAllFieldMapUint64Bytes189(populateLongMap(bytesProvider));
builder.putAllFieldMapUint64Double190(populateLongMap(doubleProvider));
builder.putAllFieldMapUint64Enum191(populateLongMap(enumProvider));
builder.putAllFieldMapUint64Fixed32192(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Fixed64193(populateLongMap(longProvider));
builder.putAllFieldMapUint64Float194(populateLongMap(floatProvider));
builder.putAllFieldMapUint64Int32195(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Int64196(populateLongMap(longProvider));
builder.putAllFieldMapUint64Message197(populateLongMap(messageProvider));
builder.putAllFieldMapUint64Sfixed32198(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Sfixed64199(populateLongMap(longProvider));
builder.putAllFieldMapUint64Sint32200(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Sint64201(populateLongMap(longProvider));
builder.putAllFieldMapUint64String202(populateLongMap(stringProvider));
builder.putAllFieldMapUint64Uint32203(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Uint64204(populateLongMap(longProvider));
return builder.build();
}
public List<Proto2MessageLite> newMessagesMissingRequiredFields() {
List<Proto2MessageLite> results = new ArrayList<>();
for (int i = 71; i <= 88; ++i) {
Proto2MessageLite.Builder builder = Proto2MessageLite.newBuilder();
populateRequiredFields(builder, i);
results.add(builder.buildPartial());
}
{
// A nested optional message field is missing required fields.
Proto2MessageLite.Builder builder = Proto2MessageLite.newBuilder();
populateRequiredFields(builder, INCLUDE_ALL_REQUIRED_FIELDS);
builder.setFieldMessage10(Proto2MessageLite.getDefaultInstance());
results.add(builder.buildPartial());
}
{
// A nested repeated message field is missing required fields.
Proto2MessageLite.Builder builder = Proto2MessageLite.newBuilder();
populateRequiredFields(builder, INCLUDE_ALL_REQUIRED_FIELDS);
builder.addFieldMessageList27(Proto2MessageLite.getDefaultInstance());
results.add(builder.buildPartial());
}
{
// A nested oneof message field is missing required fields.
Proto2MessageLite.Builder builder = Proto2MessageLite.newBuilder();
populateRequiredFields(builder, INCLUDE_ALL_REQUIRED_FIELDS);
builder.setFieldMessage62(Proto2MessageLite.getDefaultInstance());
results.add(builder.buildPartial());
}
return results;
}
// 0 is not a valid field number so we use it to mean no fields are excluded.
private static final int INCLUDE_ALL_REQUIRED_FIELDS = 0;
private void populateRequiredFields(Proto2MessageLite.Builder builder, int excludedFieldNumber) {
if (excludedFieldNumber != 71) {
builder.setFieldRequiredDouble71(data.getDouble());
}
if (excludedFieldNumber != 72) {
builder.setFieldRequiredFloat72(data.getFloat());
}
if (excludedFieldNumber != 73) {
builder.setFieldRequiredInt6473(data.getLong());
}
if (excludedFieldNumber != 74) {
builder.setFieldRequiredUint6474(data.getLong());
}
if (excludedFieldNumber != 75) {
builder.setFieldRequiredInt3275(data.getInt());
}
if (excludedFieldNumber != 76) {
builder.setFieldRequiredFixed6476(data.getLong());
}
if (excludedFieldNumber != 77) {
builder.setFieldRequiredFixed3277(data.getInt());
}
if (excludedFieldNumber != 78) {
builder.setFieldRequiredBool78(data.getBool());
}
if (excludedFieldNumber != 79) {
builder.setFieldRequiredString79(data.getString());
}
if (excludedFieldNumber != 80) {
builder.setFieldRequiredMessage80(
Proto2MessageLite.RequiredNestedMessage.newBuilder().setValue(data.getInt()));
}
if (excludedFieldNumber != 81) {
builder.setFieldRequiredBytes81(data.getBytes());
}
if (excludedFieldNumber != 82) {
builder.setFieldRequiredUint3282(data.getInt());
}
if (excludedFieldNumber != 83) {
builder.setFieldRequiredEnum83(Proto2MessageLite.TestEnum.forNumber(data.getEnum()));
}
if (excludedFieldNumber != 84) {
builder.setFieldRequiredSfixed3284(data.getInt());
}
if (excludedFieldNumber != 85) {
builder.setFieldRequiredSfixed6485(data.getLong());
}
if (excludedFieldNumber != 86) {
builder.setFieldRequiredSint3286(data.getInt());
}
if (excludedFieldNumber != 87) {
builder.setFieldRequiredSint6487(data.getLong());
}
if (excludedFieldNumber != 88) {
builder.setFieldRequiredGroup88(
Proto2MessageLite.FieldRequiredGroup88.newBuilder().setFieldInt3289(data.getInt()));
}
}
}

View File

@ -0,0 +1,49 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.testing.Proto2Testing.Proto2Message;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class Proto2SchemaTest extends AbstractProto2SchemaTest {
@Override
protected Schema<Proto2Message> schema() {
return TestSchemas.genericProto2Schema;
}
@Override
protected void registerSchemas() {
TestSchemas.registerGenericProto2Schemas();
}
}

View File

@ -0,0 +1,111 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.Descriptors.FieldDescriptor;
import protobuf_unittest.UnittestProto;
import protobuf_unittest.UnittestProto.TestAllExtensions;
import protobuf_unittest.UnittestProto.TestAllTypes;
import junit.framework.TestCase;
/** Unit tests for proto2 that treats unknown enum values as unknown fields. */
public class Proto2UnknownEnumValueTest extends TestCase {
FieldDescriptor singularField =
TestAllTypes.getDescriptor().findFieldByName("optional_nested_enum");
FieldDescriptor repeatedField =
TestAllTypes.getDescriptor().findFieldByName("repeated_nested_enum");
byte[] payload = buildPayloadWithUnknownEnumValues();
private byte[] buildPayloadWithUnknownEnumValues() {
// Builds a payload with unknown enum values.
UnknownFieldSet.Builder builder = UnknownFieldSet.newBuilder();
builder.addField(
singularField.getNumber(),
UnknownFieldSet.Field.newBuilder()
.addVarint(TestAllTypes.NestedEnum.BAR.getNumber())
.addVarint(1901 /* unknown enum value */)
.build());
builder.addField(
repeatedField.getNumber(),
UnknownFieldSet.Field.newBuilder()
.addVarint(TestAllTypes.NestedEnum.FOO.getNumber())
.addVarint(1902 /* unknown enum value */)
.addVarint(TestAllTypes.NestedEnum.BAZ.getNumber())
.addVarint(1903 /* unknown enum value */)
.build());
return builder.build().toByteArray();
}
public void testUnknownEnumValues() throws Exception {
TestAllTypes message = TestAllTypes.parseFrom(payload);
// Known enum values should be preserved.
assertEquals(TestAllTypes.NestedEnum.BAR, message.getOptionalNestedEnum());
assertEquals(2, message.getRepeatedNestedEnumList().size());
assertEquals(TestAllTypes.NestedEnum.FOO, message.getRepeatedNestedEnum(0));
assertEquals(TestAllTypes.NestedEnum.BAZ, message.getRepeatedNestedEnum(1));
// Unknown enum values should be found in UnknownFieldSet.
UnknownFieldSet unknown = message.getUnknownFields();
assertEquals(
1901, unknown.getField(singularField.getNumber()).getVarintList().get(0).longValue());
assertEquals(
1902, unknown.getField(repeatedField.getNumber()).getVarintList().get(0).longValue());
assertEquals(
1903, unknown.getField(repeatedField.getNumber()).getVarintList().get(1).longValue());
}
public void testExtensionUnknownEnumValues() throws Exception {
ExtensionRegistry registry = ExtensionRegistry.newInstance();
UnittestProto.registerAllExtensions(registry);
TestAllExtensions message = TestAllExtensions.parseFrom(payload, registry);
assertEquals(
TestAllTypes.NestedEnum.BAR,
message.getExtension(UnittestProto.optionalNestedEnumExtension));
assertEquals(2, message.getExtension(UnittestProto.repeatedNestedEnumExtension).size());
assertEquals(
TestAllTypes.NestedEnum.FOO,
message.getExtension(UnittestProto.repeatedNestedEnumExtension, 0));
assertEquals(
TestAllTypes.NestedEnum.BAZ,
message.getExtension(UnittestProto.repeatedNestedEnumExtension, 1));
// Unknown enum values should be found in UnknownFieldSet.
UnknownFieldSet unknown = message.getUnknownFields();
assertEquals(
1901, unknown.getField(singularField.getNumber()).getVarintList().get(0).longValue());
assertEquals(
1902, unknown.getField(repeatedField.getNumber()).getVarintList().get(0).longValue());
assertEquals(
1903, unknown.getField(repeatedField.getNumber()).getVarintList().get(1).longValue());
}
}

View File

@ -0,0 +1,49 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.testing.Proto3TestingLite.Proto3MessageLite;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class Proto3LiteSchemaTest extends AbstractProto3LiteSchemaTest {
@Override
protected Schema<Proto3MessageLite> schema() {
return TestSchemasLite.genericProto3LiteSchema;
}
@Override
protected void registerSchemas() {
TestSchemasLite.registerGenericProto3LiteSchemas();
}
}

View File

@ -0,0 +1,450 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.testing.Proto3Testing.Proto3Message;
import com.google.protobuf.testing.Proto3Testing.Proto3MessageWithMaps;
import java.util.HashMap;
import java.util.Map;
/** Creates instances of {@link Proto3Message} based on the tree configuration. */
public final class Proto3MessageFactory implements ExperimentalMessageFactory<Proto3Message> {
private final int numRepeatedFields;
private final int branchingFactor;
private final Proto3MessageFactory nextLevel;
private final ExperimentalTestDataProvider data;
public Proto3MessageFactory(
int numRepeatedFields, int stringLength, int branchingFactor, int treeDepth) {
this(
new ExperimentalTestDataProvider(stringLength),
numRepeatedFields,
branchingFactor,
treeDepth);
}
private Proto3MessageFactory(
ExperimentalTestDataProvider data,
int numRepeatedFields,
int branchingFactor,
int treeDepth) {
this.numRepeatedFields = numRepeatedFields;
this.branchingFactor = branchingFactor;
this.data = data;
if (treeDepth > 0) {
nextLevel = new Proto3MessageFactory(data, numRepeatedFields, branchingFactor, treeDepth - 1);
} else {
nextLevel = null;
}
}
@Override
public ExperimentalTestDataProvider dataProvider() {
return data;
}
@Override
public Proto3Message newMessage() {
Proto3Message.Builder builder = Proto3Message.newBuilder();
builder.setFieldDouble1(data.getDouble());
builder.setFieldFloat2(data.getFloat());
builder.setFieldInt643(data.getLong());
builder.setFieldUint644(data.getLong());
builder.setFieldInt325(data.getInt());
builder.setFieldFixed646(data.getLong());
builder.setFieldFixed327(data.getInt());
builder.setFieldBool8(data.getBool());
builder.setFieldString9(data.getString());
// We don't populate the message field. Instead we apply the branching factor to the
// repeated message field below.
builder.setFieldBytes11(data.getBytes());
builder.setFieldUint3212(data.getInt());
builder.setFieldEnum13Value(data.getEnum());
builder.setFieldSfixed3214(data.getInt());
builder.setFieldSfixed6415(data.getLong());
builder.setFieldSint3216(data.getInt());
builder.setFieldSint6417(data.getLong());
for (int i = 0; i < numRepeatedFields; ++i) {
builder.addFieldDoubleList18(data.getDouble());
builder.addFieldFloatList19(data.getFloat());
builder.addFieldInt64List20(data.getLong());
builder.addFieldUint64List21(data.getLong());
builder.addFieldInt32List22(data.getInt());
builder.addFieldFixed64List23(data.getLong());
builder.addFieldFixed32List24(data.getInt());
builder.addFieldBoolList25(data.getBool());
builder.addFieldStringList26(data.getString());
// Repeated message field is controlled by the branching factor below.
builder.addFieldBytesList28(data.getBytes());
builder.addFieldUint32List29(data.getInt());
builder.addFieldEnumList30Value(data.getEnum());
builder.addFieldSfixed32List31(data.getInt());
builder.addFieldSfixed64List32(data.getLong());
builder.addFieldSint32List33(data.getInt());
builder.addFieldSint64List34(data.getLong());
builder.addFieldDoubleListPacked35(data.getDouble());
builder.addFieldFloatListPacked36(data.getFloat());
builder.addFieldInt64ListPacked37(data.getLong());
builder.addFieldUint64ListPacked38(data.getLong());
builder.addFieldInt32ListPacked39(data.getInt());
builder.addFieldFixed64ListPacked40(data.getLong());
builder.addFieldFixed32ListPacked41(data.getInt());
builder.addFieldBoolListPacked42(data.getBool());
builder.addFieldUint32ListPacked43(data.getInt());
builder.addFieldEnumListPacked44Value(data.getEnum());
builder.addFieldSfixed32ListPacked45(data.getInt());
builder.addFieldSfixed64ListPacked46(data.getLong());
builder.addFieldSint32ListPacked47(data.getInt());
builder.addFieldSint64ListPacked48(data.getLong());
}
// Handle the branching factor.
if (nextLevel != null) {
for (int i = 0; i < branchingFactor; ++i) {
builder.addFieldMessageList27(nextLevel.newMessage());
}
}
return builder.build();
}
private interface MapValueProvider<T> {
public T getValue();
}
private final MapValueProvider<Integer> integerProvider =
new MapValueProvider<Integer>() {
@Override
public Integer getValue() {
return data.getInt();
}
};
private final MapValueProvider<Long> longProvider =
new MapValueProvider<Long>() {
@Override
public Long getValue() {
return data.getLong();
}
};
private final MapValueProvider<String> stringProvider =
new MapValueProvider<String>() {
@Override
public String getValue() {
return data.getString();
}
};
private final MapValueProvider<ByteString> bytesProvider =
new MapValueProvider<ByteString>() {
@Override
public ByteString getValue() {
return data.getBytes();
}
};
private final MapValueProvider<Boolean> booleanProvider =
new MapValueProvider<Boolean>() {
@Override
public Boolean getValue() {
return data.getBool();
}
};
private final MapValueProvider<Float> floatProvider =
new MapValueProvider<Float>() {
@Override
public Float getValue() {
return data.getFloat();
}
};
private final MapValueProvider<Double> doubleProvider =
new MapValueProvider<Double>() {
@Override
public Double getValue() {
return data.getDouble();
}
};
private final MapValueProvider<Proto3Message> messageProvider =
new MapValueProvider<Proto3Message>() {
@Override
public Proto3Message getValue() {
return newMessage();
}
};
private final MapValueProvider<Proto3Message.TestEnum> enumProvider =
new MapValueProvider<Proto3Message.TestEnum>() {
@Override
public Proto3Message.TestEnum getValue() {
return Proto3Message.TestEnum.forNumber(data.getEnum());
}
};
private <V> Map<Integer, V> populateIntegerMap(MapValueProvider<V> provider) {
Map<Integer, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getInt(), provider.getValue());
}
return map;
}
private <V> Map<Long, V> populateLongMap(MapValueProvider<V> provider) {
Map<Long, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getLong(), provider.getValue());
}
return map;
}
private <V> Map<String, V> populateStringMap(MapValueProvider<V> provider) {
Map<String, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getString(), provider.getValue());
}
return map;
}
private <V> Map<Boolean, V> populateBooleanMap(MapValueProvider<V> provider) {
Map<Boolean, V> map = new HashMap<>();
map.put(false, provider.getValue());
map.put(true, provider.getValue());
return map;
}
public Proto3MessageWithMaps newMessageWithMaps() {
Proto3MessageWithMaps.Builder builder = Proto3MessageWithMaps.newBuilder();
builder.putAllFieldMapBoolBool1(populateBooleanMap(booleanProvider));
builder.putAllFieldMapBoolBytes2(populateBooleanMap(bytesProvider));
builder.putAllFieldMapBoolDouble3(populateBooleanMap(doubleProvider));
builder.putAllFieldMapBoolEnum4(populateBooleanMap(enumProvider));
builder.putAllFieldMapBoolFixed325(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolFixed646(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolFloat7(populateBooleanMap(floatProvider));
builder.putAllFieldMapBoolInt328(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolInt649(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolMessage10(populateBooleanMap(messageProvider));
builder.putAllFieldMapBoolSfixed3211(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolSfixed6412(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolSint3213(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolSint6414(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolString15(populateBooleanMap(stringProvider));
builder.putAllFieldMapBoolUint3216(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolUint6417(populateBooleanMap(longProvider));
builder.putAllFieldMapFixed32Bool18(populateIntegerMap(booleanProvider));
builder.putAllFieldMapFixed32Bytes19(populateIntegerMap(bytesProvider));
builder.putAllFieldMapFixed32Double20(populateIntegerMap(doubleProvider));
builder.putAllFieldMapFixed32Enum21(populateIntegerMap(enumProvider));
builder.putAllFieldMapFixed32Fixed3222(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Fixed6423(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Float24(populateIntegerMap(floatProvider));
builder.putAllFieldMapFixed32Int3225(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Int6426(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Message27(populateIntegerMap(messageProvider));
builder.putAllFieldMapFixed32Sfixed3228(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Sfixed6429(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Sint3230(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Sint6431(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32String32(populateIntegerMap(stringProvider));
builder.putAllFieldMapFixed32Uint3233(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Uint6434(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed64Bool35(populateLongMap(booleanProvider));
builder.putAllFieldMapFixed64Bytes36(populateLongMap(bytesProvider));
builder.putAllFieldMapFixed64Double37(populateLongMap(doubleProvider));
builder.putAllFieldMapFixed64Enum38(populateLongMap(enumProvider));
builder.putAllFieldMapFixed64Fixed3239(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Fixed6440(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Float41(populateLongMap(floatProvider));
builder.putAllFieldMapFixed64Int3242(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Int6443(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Message44(populateLongMap(messageProvider));
builder.putAllFieldMapFixed64Sfixed3245(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Sfixed6446(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Sint3247(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Sint6448(populateLongMap(longProvider));
builder.putAllFieldMapFixed64String49(populateLongMap(stringProvider));
builder.putAllFieldMapFixed64Uint3250(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Uint6451(populateLongMap(longProvider));
builder.putAllFieldMapInt32Bool52(populateIntegerMap(booleanProvider));
builder.putAllFieldMapInt32Bytes53(populateIntegerMap(bytesProvider));
builder.putAllFieldMapInt32Double54(populateIntegerMap(doubleProvider));
builder.putAllFieldMapInt32Enum55(populateIntegerMap(enumProvider));
builder.putAllFieldMapInt32Fixed3256(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Fixed6457(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Float58(populateIntegerMap(floatProvider));
builder.putAllFieldMapInt32Int3259(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Int6460(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Message61(populateIntegerMap(messageProvider));
builder.putAllFieldMapInt32Sfixed3262(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Sfixed6463(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Sint3264(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Sint6465(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32String66(populateIntegerMap(stringProvider));
builder.putAllFieldMapInt32Uint3267(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Uint6468(populateIntegerMap(longProvider));
builder.putAllFieldMapInt64Bool69(populateLongMap(booleanProvider));
builder.putAllFieldMapInt64Bytes70(populateLongMap(bytesProvider));
builder.putAllFieldMapInt64Double71(populateLongMap(doubleProvider));
builder.putAllFieldMapInt64Enum72(populateLongMap(enumProvider));
builder.putAllFieldMapInt64Fixed3273(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Fixed6474(populateLongMap(longProvider));
builder.putAllFieldMapInt64Float75(populateLongMap(floatProvider));
builder.putAllFieldMapInt64Int3276(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Int6477(populateLongMap(longProvider));
builder.putAllFieldMapInt64Message78(populateLongMap(messageProvider));
builder.putAllFieldMapInt64Sfixed3279(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Sfixed6480(populateLongMap(longProvider));
builder.putAllFieldMapInt64Sint3281(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Sint6482(populateLongMap(longProvider));
builder.putAllFieldMapInt64String83(populateLongMap(stringProvider));
builder.putAllFieldMapInt64Uint3284(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Uint6485(populateLongMap(longProvider));
builder.putAllFieldMapSfixed32Bool86(populateIntegerMap(booleanProvider));
builder.putAllFieldMapSfixed32Bytes87(populateIntegerMap(bytesProvider));
builder.putAllFieldMapSfixed32Double88(populateIntegerMap(doubleProvider));
builder.putAllFieldMapSfixed32Enum89(populateIntegerMap(enumProvider));
builder.putAllFieldMapSfixed32Fixed3290(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Fixed6491(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Float92(populateIntegerMap(floatProvider));
builder.putAllFieldMapSfixed32Int3293(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Int6494(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Message95(populateIntegerMap(messageProvider));
builder.putAllFieldMapSfixed32Sfixed3296(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Sfixed6497(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Sint3298(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Sint6499(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32String100(populateIntegerMap(stringProvider));
builder.putAllFieldMapSfixed32Uint32101(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Uint64102(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed64Bool103(populateLongMap(booleanProvider));
builder.putAllFieldMapSfixed64Bytes104(populateLongMap(bytesProvider));
builder.putAllFieldMapSfixed64Double105(populateLongMap(doubleProvider));
builder.putAllFieldMapSfixed64Enum106(populateLongMap(enumProvider));
builder.putAllFieldMapSfixed64Fixed32107(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Fixed64108(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Float109(populateLongMap(floatProvider));
builder.putAllFieldMapSfixed64Int32110(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Int64111(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Message112(populateLongMap(messageProvider));
builder.putAllFieldMapSfixed64Sfixed32113(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Sfixed64114(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Sint32115(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Sint64116(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64String117(populateLongMap(stringProvider));
builder.putAllFieldMapSfixed64Uint32118(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Uint64119(populateLongMap(longProvider));
builder.putAllFieldMapSint32Bool120(populateIntegerMap(booleanProvider));
builder.putAllFieldMapSint32Bytes121(populateIntegerMap(bytesProvider));
builder.putAllFieldMapSint32Double122(populateIntegerMap(doubleProvider));
builder.putAllFieldMapSint32Enum123(populateIntegerMap(enumProvider));
builder.putAllFieldMapSint32Fixed32124(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Fixed64125(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Float126(populateIntegerMap(floatProvider));
builder.putAllFieldMapSint32Int32127(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Int64128(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Message129(populateIntegerMap(messageProvider));
builder.putAllFieldMapSint32Sfixed32130(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Sfixed64131(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Sint32132(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Sint64133(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32String134(populateIntegerMap(stringProvider));
builder.putAllFieldMapSint32Uint32135(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Uint64136(populateIntegerMap(longProvider));
builder.putAllFieldMapSint64Bool137(populateLongMap(booleanProvider));
builder.putAllFieldMapSint64Bytes138(populateLongMap(bytesProvider));
builder.putAllFieldMapSint64Double139(populateLongMap(doubleProvider));
builder.putAllFieldMapSint64Enum140(populateLongMap(enumProvider));
builder.putAllFieldMapSint64Fixed32141(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Fixed64142(populateLongMap(longProvider));
builder.putAllFieldMapSint64Float143(populateLongMap(floatProvider));
builder.putAllFieldMapSint64Int32144(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Int64145(populateLongMap(longProvider));
builder.putAllFieldMapSint64Message146(populateLongMap(messageProvider));
builder.putAllFieldMapSint64Sfixed32147(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Sfixed64148(populateLongMap(longProvider));
builder.putAllFieldMapSint64Sint32149(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Sint64150(populateLongMap(longProvider));
builder.putAllFieldMapSint64String151(populateLongMap(stringProvider));
builder.putAllFieldMapSint64Uint32152(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Uint64153(populateLongMap(longProvider));
builder.putAllFieldMapStringBool154(populateStringMap(booleanProvider));
builder.putAllFieldMapStringBytes155(populateStringMap(bytesProvider));
builder.putAllFieldMapStringDouble156(populateStringMap(doubleProvider));
builder.putAllFieldMapStringEnum157(populateStringMap(enumProvider));
builder.putAllFieldMapStringFixed32158(populateStringMap(integerProvider));
builder.putAllFieldMapStringFixed64159(populateStringMap(longProvider));
builder.putAllFieldMapStringFloat160(populateStringMap(floatProvider));
builder.putAllFieldMapStringInt32161(populateStringMap(integerProvider));
builder.putAllFieldMapStringInt64162(populateStringMap(longProvider));
builder.putAllFieldMapStringMessage163(populateStringMap(messageProvider));
builder.putAllFieldMapStringSfixed32164(populateStringMap(integerProvider));
builder.putAllFieldMapStringSfixed64165(populateStringMap(longProvider));
builder.putAllFieldMapStringSint32166(populateStringMap(integerProvider));
builder.putAllFieldMapStringSint64167(populateStringMap(longProvider));
builder.putAllFieldMapStringString168(populateStringMap(stringProvider));
builder.putAllFieldMapStringUint32169(populateStringMap(integerProvider));
builder.putAllFieldMapStringUint64170(populateStringMap(longProvider));
builder.putAllFieldMapUint32Bool171(populateIntegerMap(booleanProvider));
builder.putAllFieldMapUint32Bytes172(populateIntegerMap(bytesProvider));
builder.putAllFieldMapUint32Double173(populateIntegerMap(doubleProvider));
builder.putAllFieldMapUint32Enum174(populateIntegerMap(enumProvider));
builder.putAllFieldMapUint32Fixed32175(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Fixed64176(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Float177(populateIntegerMap(floatProvider));
builder.putAllFieldMapUint32Int32178(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Int64179(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Message180(populateIntegerMap(messageProvider));
builder.putAllFieldMapUint32Sfixed32181(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Sfixed64182(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Sint32183(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Sint64184(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32String185(populateIntegerMap(stringProvider));
builder.putAllFieldMapUint32Uint32186(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Uint64187(populateIntegerMap(longProvider));
builder.putAllFieldMapUint64Bool188(populateLongMap(booleanProvider));
builder.putAllFieldMapUint64Bytes189(populateLongMap(bytesProvider));
builder.putAllFieldMapUint64Double190(populateLongMap(doubleProvider));
builder.putAllFieldMapUint64Enum191(populateLongMap(enumProvider));
builder.putAllFieldMapUint64Fixed32192(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Fixed64193(populateLongMap(longProvider));
builder.putAllFieldMapUint64Float194(populateLongMap(floatProvider));
builder.putAllFieldMapUint64Int32195(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Int64196(populateLongMap(longProvider));
builder.putAllFieldMapUint64Message197(populateLongMap(messageProvider));
builder.putAllFieldMapUint64Sfixed32198(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Sfixed64199(populateLongMap(longProvider));
builder.putAllFieldMapUint64Sint32200(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Sint64201(populateLongMap(longProvider));
builder.putAllFieldMapUint64String202(populateLongMap(stringProvider));
builder.putAllFieldMapUint64Uint32203(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Uint64204(populateLongMap(longProvider));
return builder.build();
}
}

View File

@ -0,0 +1,506 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import static com.google.protobuf.FieldInfo.forField;
import static com.google.protobuf.FieldInfo.forMapField;
import static com.google.protobuf.FieldInfo.forOneofMemberField;
import static com.google.protobuf.FieldInfo.forRepeatedMessageField;
import com.google.protobuf.testing.Proto2Testing.Proto2MessageWithMaps;
import com.google.protobuf.testing.Proto3Testing.Proto3Empty;
import com.google.protobuf.testing.Proto3Testing.Proto3Message;
import com.google.protobuf.testing.Proto3Testing.Proto3MessageWithMaps;
import java.lang.reflect.Field;
/** A factory that generates a hard-coded info for {@link Proto3Message}. */
public final class Proto3MessageInfoFactory implements MessageInfoFactory {
private static final Proto3MessageInfoFactory INSTANCE = new Proto3MessageInfoFactory();
private Proto3MessageInfoFactory() {}
public static Proto3MessageInfoFactory getInstance() {
return INSTANCE;
}
@Override
public boolean isSupported(Class<?> clazz) {
return true;
}
@Override
public MessageInfo messageInfoFor(Class<?> clazz) {
if (Proto3Message.class.isAssignableFrom(clazz)) {
return newMessageInfoForProto3Message();
} else if (Proto3Empty.class.isAssignableFrom(clazz)) {
return newMessageInfoForProto3Empty();
} else if (Proto3MessageWithMaps.class.isAssignableFrom(clazz)) {
return newMessageInfoForProto3MessageWithMaps();
} else {
throw new IllegalArgumentException("Unsupported class: " + clazz.getName());
}
}
/**
* Creates a new hard-coded info for {@link Proto3Message}. Each time this is called, we manually
* go through the entire process of what a message would do if it self-registered its own info,
* including looking up each field by name. This is done for benchmarking purposes, so that we get
* a more accurate representation of the time it takes to perform this process.
*/
private static StructuralMessageInfo newMessageInfoForProto3Message() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(48);
lookupFieldsByName(builder);
return builder.build();
}
private static void lookupFieldsByName(StructuralMessageInfo.Builder builder) {
builder.withDefaultInstance(Proto3Message.getDefaultInstance());
builder.withSyntax(ProtoSyntax.PROTO3);
builder.withField(forField(field("fieldDouble1_"), 1, FieldType.DOUBLE, true));
builder.withField(forField(field("fieldFloat2_"), 2, FieldType.FLOAT, true));
builder.withField(forField(field("fieldInt643_"), 3, FieldType.INT64, true));
builder.withField(forField(field("fieldUint644_"), 4, FieldType.UINT64, true));
builder.withField(forField(field("fieldInt325_"), 5, FieldType.INT32, true));
builder.withField(forField(field("fieldFixed646_"), 6, FieldType.FIXED64, true));
builder.withField(forField(field("fieldFixed327_"), 7, FieldType.FIXED32, true));
builder.withField(forField(field("fieldBool8_"), 8, FieldType.BOOL, true));
builder.withField(forField(field("fieldString9_"), 9, FieldType.STRING, true));
builder.withField(forField(field("fieldMessage10_"), 10, FieldType.MESSAGE, true));
builder.withField(forField(field("fieldBytes11_"), 11, FieldType.BYTES, true));
builder.withField(forField(field("fieldUint3212_"), 12, FieldType.UINT32, true));
builder.withField(forField(field("fieldEnum13_"), 13, FieldType.ENUM, true));
builder.withField(forField(field("fieldSfixed3214_"), 14, FieldType.SFIXED32, true));
builder.withField(forField(field("fieldSfixed6415_"), 15, FieldType.SFIXED64, true));
builder.withField(forField(field("fieldSint3216_"), 16, FieldType.SINT32, true));
builder.withField(forField(field("fieldSint6417_"), 17, FieldType.SINT64, true));
builder.withField(forField(field("fieldDoubleList18_"), 18, FieldType.DOUBLE_LIST, true));
builder.withField(forField(field("fieldFloatList19_"), 19, FieldType.FLOAT_LIST, true));
builder.withField(forField(field("fieldInt64List20_"), 20, FieldType.INT64_LIST, true));
builder.withField(forField(field("fieldUint64List21_"), 21, FieldType.UINT64_LIST, true));
builder.withField(forField(field("fieldInt32List22_"), 22, FieldType.INT32_LIST, true));
builder.withField(forField(field("fieldFixed64List23_"), 23, FieldType.FIXED64_LIST, true));
builder.withField(forField(field("fieldFixed32List24_"), 24, FieldType.FIXED32_LIST, true));
builder.withField(forField(field("fieldBoolList25_"), 25, FieldType.BOOL_LIST, true));
builder.withField(forField(field("fieldStringList26_"), 26, FieldType.STRING_LIST, true));
builder.withField(
forRepeatedMessageField(
field("fieldMessageList27_"), 27, FieldType.MESSAGE_LIST, Proto3Message.class));
builder.withField(forField(field("fieldBytesList28_"), 28, FieldType.BYTES_LIST, true));
builder.withField(forField(field("fieldUint32List29_"), 29, FieldType.UINT32_LIST, true));
builder.withField(forField(field("fieldEnumList30_"), 30, FieldType.ENUM_LIST, true));
builder.withField(forField(field("fieldSfixed32List31_"), 31, FieldType.SFIXED32_LIST, true));
builder.withField(forField(field("fieldSfixed64List32_"), 32, FieldType.SFIXED64_LIST, true));
builder.withField(forField(field("fieldSint32List33_"), 33, FieldType.SINT32_LIST, true));
builder.withField(forField(field("fieldSint64List34_"), 34, FieldType.SINT64_LIST, true));
builder.withField(
forField(field("fieldDoubleListPacked35_"), 35, FieldType.DOUBLE_LIST_PACKED, true));
builder.withField(
forField(field("fieldFloatListPacked36_"), 36, FieldType.FLOAT_LIST_PACKED, true));
builder.withField(
forField(field("fieldInt64ListPacked37_"), 37, FieldType.INT64_LIST_PACKED, true));
builder.withField(
forField(field("fieldUint64ListPacked38_"), 38, FieldType.UINT64_LIST_PACKED, true));
builder.withField(
forField(field("fieldInt32ListPacked39_"), 39, FieldType.INT32_LIST_PACKED, true));
builder.withField(
forField(field("fieldFixed64ListPacked40_"), 40, FieldType.FIXED64_LIST_PACKED, true));
builder.withField(
forField(field("fieldFixed32ListPacked41_"), 41, FieldType.FIXED32_LIST_PACKED, true));
builder.withField(
forField(field("fieldBoolListPacked42_"), 42, FieldType.BOOL_LIST_PACKED, true));
builder.withField(
forField(field("fieldUint32ListPacked43_"), 43, FieldType.UINT32_LIST_PACKED, true));
builder.withField(
forField(field("fieldEnumListPacked44_"), 44, FieldType.ENUM_LIST_PACKED, true));
builder.withField(
forField(field("fieldSfixed32ListPacked45_"), 45, FieldType.SFIXED32_LIST_PACKED, true));
builder.withField(
forField(field("fieldSfixed64ListPacked46_"), 46, FieldType.SFIXED64_LIST_PACKED, true));
builder.withField(
forField(field("fieldSint32ListPacked47_"), 47, FieldType.SINT32_LIST_PACKED, true));
builder.withField(
forField(field("fieldSint64ListPacked48_"), 48, FieldType.SINT64_LIST_PACKED, true));
OneofInfo oneof = new OneofInfo(0, field("testOneofCase_"), field("testOneof_"));
builder.withField(forOneofMemberField(53, FieldType.DOUBLE, oneof, Double.class, true, null));
builder.withField(forOneofMemberField(54, FieldType.FLOAT, oneof, Float.class, true, null));
builder.withField(forOneofMemberField(55, FieldType.INT64, oneof, Long.class, true, null));
builder.withField(forOneofMemberField(56, FieldType.UINT64, oneof, Long.class, true, null));
builder.withField(forOneofMemberField(57, FieldType.INT32, oneof, Integer.class, true, null));
builder.withField(forOneofMemberField(58, FieldType.FIXED64, oneof, Long.class, true, null));
builder.withField(forOneofMemberField(59, FieldType.FIXED32, oneof, Integer.class, true, null));
builder.withField(forOneofMemberField(60, FieldType.BOOL, oneof, Boolean.class, true, null));
builder.withField(forOneofMemberField(61, FieldType.STRING, oneof, String.class, true, null));
builder.withField(
forOneofMemberField(62, FieldType.MESSAGE, oneof, Proto3Message.class, true, null));
builder.withField(
forOneofMemberField(63, FieldType.BYTES, oneof, ByteString.class, true, null));
builder.withField(forOneofMemberField(64, FieldType.UINT32, oneof, Integer.class, true, null));
builder.withField(
forOneofMemberField(65, FieldType.SFIXED32, oneof, Integer.class, true, null));
builder.withField(forOneofMemberField(66, FieldType.SFIXED64, oneof, Long.class, true, null));
builder.withField(forOneofMemberField(67, FieldType.SINT32, oneof, Integer.class, true, null));
builder.withField(forOneofMemberField(68, FieldType.SINT64, oneof, Long.class, true, null));
}
private StructuralMessageInfo newMessageInfoForProto3Empty() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder(1);
builder.withSyntax(ProtoSyntax.PROTO3);
return builder.build();
}
private StructuralMessageInfo newMessageInfoForProto3MessageWithMaps() {
StructuralMessageInfo.Builder builder = StructuralMessageInfo.newBuilder();
builder.withSyntax(ProtoSyntax.PROTO3);
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_bool_1", 1));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_bytes_2", 2));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_double_3", 3));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_enum_4", 4));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_fixed32_5", 5));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_fixed64_6", 6));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_float_7", 7));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_int32_8", 8));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_int64_9", 9));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_message_10", 10));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_sfixed32_11", 11));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_sfixed64_12", 12));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_sint32_13", 13));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_sint64_14", 14));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_string_15", 15));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_uint32_16", 16));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_bool_uint64_17", 17));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_bool_18", 18));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_bytes_19", 19));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_double_20", 20));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_enum_21", 21));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_fixed32_22", 22));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_fixed64_23", 23));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_float_24", 24));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_int32_25", 25));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_int64_26", 26));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_message_27", 27));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_sfixed32_28", 28));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_sfixed64_29", 29));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_sint32_30", 30));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_sint64_31", 31));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_string_32", 32));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_uint32_33", 33));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed32_uint64_34", 34));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_bool_35", 35));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_bytes_36", 36));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_double_37", 37));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_enum_38", 38));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_fixed32_39", 39));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_fixed64_40", 40));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_float_41", 41));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_int32_42", 42));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_int64_43", 43));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_message_44", 44));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_sfixed32_45", 45));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_sfixed64_46", 46));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_sint32_47", 47));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_sint64_48", 48));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_string_49", 49));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_uint32_50", 50));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_fixed64_uint64_51", 51));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_bool_52", 52));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_bytes_53", 53));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_double_54", 54));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_enum_55", 55));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_fixed32_56", 56));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_fixed64_57", 57));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_float_58", 58));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_int32_59", 59));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_int64_60", 60));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_message_61", 61));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_sfixed32_62", 62));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_sfixed64_63", 63));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_sint32_64", 64));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_sint64_65", 65));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_string_66", 66));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_uint32_67", 67));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int32_uint64_68", 68));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_bool_69", 69));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_bytes_70", 70));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_double_71", 71));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_enum_72", 72));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_fixed32_73", 73));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_fixed64_74", 74));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_float_75", 75));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_int32_76", 76));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_int64_77", 77));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_message_78", 78));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_sfixed32_79", 79));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_sfixed64_80", 80));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_sint32_81", 81));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_sint64_82", 82));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_string_83", 83));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_uint32_84", 84));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_int64_uint64_85", 85));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_bool_86", 86));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_bytes_87", 87));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_double_88", 88));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_enum_89", 89));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_fixed32_90", 90));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_fixed64_91", 91));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_float_92", 92));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_int32_93", 93));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_int64_94", 94));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_message_95", 95));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_sfixed32_96", 96));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_sfixed64_97", 97));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_sint32_98", 98));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_sint64_99", 99));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_string_100", 100));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_uint32_101", 101));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed32_uint64_102", 102));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_bool_103", 103));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_bytes_104", 104));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_double_105", 105));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_enum_106", 106));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_fixed32_107", 107));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_fixed64_108", 108));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_float_109", 109));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_int32_110", 110));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_int64_111", 111));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_message_112", 112));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_sfixed32_113", 113));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_sfixed64_114", 114));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_sint32_115", 115));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_sint64_116", 116));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_string_117", 117));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_uint32_118", 118));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sfixed64_uint64_119", 119));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_bool_120", 120));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_bytes_121", 121));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_double_122", 122));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_enum_123", 123));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_fixed32_124", 124));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_fixed64_125", 125));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_float_126", 126));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_int32_127", 127));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_int64_128", 128));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_message_129", 129));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_sfixed32_130", 130));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_sfixed64_131", 131));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_sint32_132", 132));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_sint64_133", 133));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_string_134", 134));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_uint32_135", 135));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint32_uint64_136", 136));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_bool_137", 137));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_bytes_138", 138));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_double_139", 139));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_enum_140", 140));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_fixed32_141", 141));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_fixed64_142", 142));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_float_143", 143));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_int32_144", 144));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_int64_145", 145));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_message_146", 146));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_sfixed32_147", 147));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_sfixed64_148", 148));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_sint32_149", 149));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_sint64_150", 150));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_string_151", 151));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_uint32_152", 152));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_sint64_uint64_153", 153));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_bool_154", 154));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_bytes_155", 155));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_double_156", 156));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_enum_157", 157));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_fixed32_158", 158));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_fixed64_159", 159));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_float_160", 160));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_int32_161", 161));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_int64_162", 162));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_message_163", 163));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_sfixed32_164", 164));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_sfixed64_165", 165));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_sint32_166", 166));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_sint64_167", 167));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_string_168", 168));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_uint32_169", 169));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_string_uint64_170", 170));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_bool_171", 171));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_bytes_172", 172));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_double_173", 173));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_enum_174", 174));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_fixed32_175", 175));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_fixed64_176", 176));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_float_177", 177));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_int32_178", 178));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_int64_179", 179));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_message_180", 180));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_sfixed32_181", 181));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_sfixed64_182", 182));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_sint32_183", 183));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_sint64_184", 184));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_string_185", 185));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_uint32_186", 186));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint32_uint64_187", 187));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_bool_188", 188));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_bytes_189", 189));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_double_190", 190));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_enum_191", 191));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_fixed32_192", 192));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_fixed64_193", 193));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_float_194", 194));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_int32_195", 195));
builder.withField(mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_int64_196", 196));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_message_197", 197));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_sfixed32_198", 198));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_sfixed64_199", 199));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_sint32_200", 200));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_sint64_201", 201));
builder.withField(
mapFieldInfo(Proto3MessageWithMaps.class, "field_map_uint64_string_202", 202));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_uint32_203", 203));
builder.withField(
mapFieldInfo(Proto2MessageWithMaps.class, "field_map_uint64_uint64_204", 204));
return builder.build();
}
private static Field field(String name) {
return field(Proto3Message.class, name);
}
private static Field field(Class<?> clazz, String name) {
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException | SecurityException e) {
throw new RuntimeException(e);
}
}
private static FieldInfo mapFieldInfo(Class<?> clazz, String fieldName, int fieldNumber) {
try {
return forMapField(
field(clazz, SchemaUtil.toCamelCase(fieldName, false) + "_"),
fieldNumber,
SchemaUtil.getMapDefaultEntry(clazz, fieldName),
null);
} catch (Throwable t) {
throw new RuntimeException(t);
}
}
}

View File

@ -0,0 +1,452 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package com.google.protobuf;
import com.google.protobuf.testing.Proto3TestingLite.Proto3MessageLite;
import com.google.protobuf.testing.Proto3TestingLite.Proto3MessageLiteWithMaps;
import java.util.HashMap;
import java.util.Map;
/** Creates instances of {@link Proto3MessageLite} based on the tree configuration. */
public final class Proto3MessageLiteFactory
implements ExperimentalMessageFactory<Proto3MessageLite> {
private final int numRepeatedFields;
private final int branchingFactor;
private final Proto3MessageLiteFactory nextLevel;
private final ExperimentalTestDataProvider data;
public Proto3MessageLiteFactory(
int numRepeatedFields, int stringLength, int branchingFactor, int treeDepth) {
this(
new ExperimentalTestDataProvider(stringLength),
numRepeatedFields,
branchingFactor,
treeDepth);
}
private Proto3MessageLiteFactory(
ExperimentalTestDataProvider data,
int numRepeatedFields,
int branchingFactor,
int treeDepth) {
this.numRepeatedFields = numRepeatedFields;
this.branchingFactor = branchingFactor;
this.data = data;
if (treeDepth > 0) {
nextLevel =
new Proto3MessageLiteFactory(data, numRepeatedFields, branchingFactor, treeDepth - 1);
} else {
nextLevel = null;
}
}
@Override
public ExperimentalTestDataProvider dataProvider() {
return data;
}
@Override
public Proto3MessageLite newMessage() {
Proto3MessageLite.Builder builder = Proto3MessageLite.newBuilder();
builder.setFieldDouble1(data.getDouble());
builder.setFieldFloat2(data.getFloat());
builder.setFieldInt643(data.getLong());
builder.setFieldUint644(data.getLong());
builder.setFieldInt325(data.getInt());
builder.setFieldFixed646(data.getLong());
builder.setFieldFixed327(data.getInt());
builder.setFieldBool8(data.getBool());
builder.setFieldString9(data.getString());
// We don't populate the message field. Instead we apply the branching factor to the
// repeated message field below.
builder.setFieldBytes11(data.getBytes());
builder.setFieldUint3212(data.getInt());
builder.setFieldEnum13Value(data.getEnum());
builder.setFieldSfixed3214(data.getInt());
builder.setFieldSfixed6415(data.getLong());
builder.setFieldSint3216(data.getInt());
builder.setFieldSint6417(data.getLong());
for (int i = 0; i < numRepeatedFields; ++i) {
builder.addFieldDoubleList18(data.getDouble());
builder.addFieldFloatList19(data.getFloat());
builder.addFieldInt64List20(data.getLong());
builder.addFieldUint64List21(data.getLong());
builder.addFieldInt32List22(data.getInt());
builder.addFieldFixed64List23(data.getLong());
builder.addFieldFixed32List24(data.getInt());
builder.addFieldBoolList25(data.getBool());
builder.addFieldStringList26(data.getString());
// Repeated message field is controlled by the branching factor below.
builder.addFieldBytesList28(data.getBytes());
builder.addFieldUint32List29(data.getInt());
builder.addFieldEnumList30Value(data.getEnum());
builder.addFieldSfixed32List31(data.getInt());
builder.addFieldSfixed64List32(data.getLong());
builder.addFieldSint32List33(data.getInt());
builder.addFieldSint64List34(data.getLong());
builder.addFieldDoubleListPacked35(data.getDouble());
builder.addFieldFloatListPacked36(data.getFloat());
builder.addFieldInt64ListPacked37(data.getLong());
builder.addFieldUint64ListPacked38(data.getLong());
builder.addFieldInt32ListPacked39(data.getInt());
builder.addFieldFixed64ListPacked40(data.getLong());
builder.addFieldFixed32ListPacked41(data.getInt());
builder.addFieldBoolListPacked42(data.getBool());
builder.addFieldUint32ListPacked43(data.getInt());
builder.addFieldEnumListPacked44Value(data.getEnum());
builder.addFieldSfixed32ListPacked45(data.getInt());
builder.addFieldSfixed64ListPacked46(data.getLong());
builder.addFieldSint32ListPacked47(data.getInt());
builder.addFieldSint64ListPacked48(data.getLong());
}
// Handle the branching factor.
if (nextLevel != null) {
for (int i = 0; i < branchingFactor; ++i) {
builder.addFieldMessageList27(nextLevel.newMessage());
}
}
return builder.build();
}
private interface MapValueProvider<T> {
public T getValue();
}
private final MapValueProvider<Integer> integerProvider =
new MapValueProvider<Integer>() {
@Override
public Integer getValue() {
return data.getInt();
}
};
private final MapValueProvider<Long> longProvider =
new MapValueProvider<Long>() {
@Override
public Long getValue() {
return data.getLong();
}
};
private final MapValueProvider<String> stringProvider =
new MapValueProvider<String>() {
@Override
public String getValue() {
return data.getString();
}
};
private final MapValueProvider<ByteString> bytesProvider =
new MapValueProvider<ByteString>() {
@Override
public ByteString getValue() {
return data.getBytes();
}
};
private final MapValueProvider<Boolean> booleanProvider =
new MapValueProvider<Boolean>() {
@Override
public Boolean getValue() {
return data.getBool();
}
};
private final MapValueProvider<Float> floatProvider =
new MapValueProvider<Float>() {
@Override
public Float getValue() {
return data.getFloat();
}
};
private final MapValueProvider<Double> doubleProvider =
new MapValueProvider<Double>() {
@Override
public Double getValue() {
return data.getDouble();
}
};
private final MapValueProvider<Proto3MessageLite> messageProvider =
new MapValueProvider<Proto3MessageLite>() {
@Override
public Proto3MessageLite getValue() {
return newMessage();
}
};
private final MapValueProvider<Proto3MessageLite.TestEnum> enumProvider =
new MapValueProvider<Proto3MessageLite.TestEnum>() {
@Override
public Proto3MessageLite.TestEnum getValue() {
return Proto3MessageLite.TestEnum.forNumber(data.getEnum());
}
};
private <V> Map<Integer, V> populateIntegerMap(MapValueProvider<V> provider) {
Map<Integer, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getInt(), provider.getValue());
}
return map;
}
private <V> Map<Long, V> populateLongMap(MapValueProvider<V> provider) {
Map<Long, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getLong(), provider.getValue());
}
return map;
}
private <V> Map<String, V> populateStringMap(MapValueProvider<V> provider) {
Map<String, V> map = new HashMap<>();
for (int i = 0; i < numRepeatedFields; ++i) {
map.put(data.getString(), provider.getValue());
}
return map;
}
private <V> Map<Boolean, V> populateBooleanMap(MapValueProvider<V> provider) {
Map<Boolean, V> map = new HashMap<>();
map.put(false, provider.getValue());
map.put(true, provider.getValue());
return map;
}
public Proto3MessageLiteWithMaps newMessageWithMaps() {
Proto3MessageLiteWithMaps.Builder builder = Proto3MessageLiteWithMaps.newBuilder();
builder.putAllFieldMapBoolBool1(populateBooleanMap(booleanProvider));
builder.putAllFieldMapBoolBytes2(populateBooleanMap(bytesProvider));
builder.putAllFieldMapBoolDouble3(populateBooleanMap(doubleProvider));
builder.putAllFieldMapBoolEnum4(populateBooleanMap(enumProvider));
builder.putAllFieldMapBoolFixed325(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolFixed646(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolFloat7(populateBooleanMap(floatProvider));
builder.putAllFieldMapBoolInt328(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolInt649(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolMessage10(populateBooleanMap(messageProvider));
builder.putAllFieldMapBoolSfixed3211(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolSfixed6412(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolSint3213(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolSint6414(populateBooleanMap(longProvider));
builder.putAllFieldMapBoolString15(populateBooleanMap(stringProvider));
builder.putAllFieldMapBoolUint3216(populateBooleanMap(integerProvider));
builder.putAllFieldMapBoolUint6417(populateBooleanMap(longProvider));
builder.putAllFieldMapFixed32Bool18(populateIntegerMap(booleanProvider));
builder.putAllFieldMapFixed32Bytes19(populateIntegerMap(bytesProvider));
builder.putAllFieldMapFixed32Double20(populateIntegerMap(doubleProvider));
builder.putAllFieldMapFixed32Enum21(populateIntegerMap(enumProvider));
builder.putAllFieldMapFixed32Fixed3222(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Fixed6423(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Float24(populateIntegerMap(floatProvider));
builder.putAllFieldMapFixed32Int3225(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Int6426(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Message27(populateIntegerMap(messageProvider));
builder.putAllFieldMapFixed32Sfixed3228(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Sfixed6429(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32Sint3230(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Sint6431(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed32String32(populateIntegerMap(stringProvider));
builder.putAllFieldMapFixed32Uint3233(populateIntegerMap(integerProvider));
builder.putAllFieldMapFixed32Uint6434(populateIntegerMap(longProvider));
builder.putAllFieldMapFixed64Bool35(populateLongMap(booleanProvider));
builder.putAllFieldMapFixed64Bytes36(populateLongMap(bytesProvider));
builder.putAllFieldMapFixed64Double37(populateLongMap(doubleProvider));
builder.putAllFieldMapFixed64Enum38(populateLongMap(enumProvider));
builder.putAllFieldMapFixed64Fixed3239(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Fixed6440(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Float41(populateLongMap(floatProvider));
builder.putAllFieldMapFixed64Int3242(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Int6443(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Message44(populateLongMap(messageProvider));
builder.putAllFieldMapFixed64Sfixed3245(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Sfixed6446(populateLongMap(longProvider));
builder.putAllFieldMapFixed64Sint3247(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Sint6448(populateLongMap(longProvider));
builder.putAllFieldMapFixed64String49(populateLongMap(stringProvider));
builder.putAllFieldMapFixed64Uint3250(populateLongMap(integerProvider));
builder.putAllFieldMapFixed64Uint6451(populateLongMap(longProvider));
builder.putAllFieldMapInt32Bool52(populateIntegerMap(booleanProvider));
builder.putAllFieldMapInt32Bytes53(populateIntegerMap(bytesProvider));
builder.putAllFieldMapInt32Double54(populateIntegerMap(doubleProvider));
builder.putAllFieldMapInt32Enum55(populateIntegerMap(enumProvider));
builder.putAllFieldMapInt32Fixed3256(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Fixed6457(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Float58(populateIntegerMap(floatProvider));
builder.putAllFieldMapInt32Int3259(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Int6460(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Message61(populateIntegerMap(messageProvider));
builder.putAllFieldMapInt32Sfixed3262(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Sfixed6463(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32Sint3264(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Sint6465(populateIntegerMap(longProvider));
builder.putAllFieldMapInt32String66(populateIntegerMap(stringProvider));
builder.putAllFieldMapInt32Uint3267(populateIntegerMap(integerProvider));
builder.putAllFieldMapInt32Uint6468(populateIntegerMap(longProvider));
builder.putAllFieldMapInt64Bool69(populateLongMap(booleanProvider));
builder.putAllFieldMapInt64Bytes70(populateLongMap(bytesProvider));
builder.putAllFieldMapInt64Double71(populateLongMap(doubleProvider));
builder.putAllFieldMapInt64Enum72(populateLongMap(enumProvider));
builder.putAllFieldMapInt64Fixed3273(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Fixed6474(populateLongMap(longProvider));
builder.putAllFieldMapInt64Float75(populateLongMap(floatProvider));
builder.putAllFieldMapInt64Int3276(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Int6477(populateLongMap(longProvider));
builder.putAllFieldMapInt64Message78(populateLongMap(messageProvider));
builder.putAllFieldMapInt64Sfixed3279(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Sfixed6480(populateLongMap(longProvider));
builder.putAllFieldMapInt64Sint3281(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Sint6482(populateLongMap(longProvider));
builder.putAllFieldMapInt64String83(populateLongMap(stringProvider));
builder.putAllFieldMapInt64Uint3284(populateLongMap(integerProvider));
builder.putAllFieldMapInt64Uint6485(populateLongMap(longProvider));
builder.putAllFieldMapSfixed32Bool86(populateIntegerMap(booleanProvider));
builder.putAllFieldMapSfixed32Bytes87(populateIntegerMap(bytesProvider));
builder.putAllFieldMapSfixed32Double88(populateIntegerMap(doubleProvider));
builder.putAllFieldMapSfixed32Enum89(populateIntegerMap(enumProvider));
builder.putAllFieldMapSfixed32Fixed3290(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Fixed6491(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Float92(populateIntegerMap(floatProvider));
builder.putAllFieldMapSfixed32Int3293(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Int6494(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Message95(populateIntegerMap(messageProvider));
builder.putAllFieldMapSfixed32Sfixed3296(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Sfixed6497(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32Sint3298(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Sint6499(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed32String100(populateIntegerMap(stringProvider));
builder.putAllFieldMapSfixed32Uint32101(populateIntegerMap(integerProvider));
builder.putAllFieldMapSfixed32Uint64102(populateIntegerMap(longProvider));
builder.putAllFieldMapSfixed64Bool103(populateLongMap(booleanProvider));
builder.putAllFieldMapSfixed64Bytes104(populateLongMap(bytesProvider));
builder.putAllFieldMapSfixed64Double105(populateLongMap(doubleProvider));
builder.putAllFieldMapSfixed64Enum106(populateLongMap(enumProvider));
builder.putAllFieldMapSfixed64Fixed32107(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Fixed64108(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Float109(populateLongMap(floatProvider));
builder.putAllFieldMapSfixed64Int32110(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Int64111(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Message112(populateLongMap(messageProvider));
builder.putAllFieldMapSfixed64Sfixed32113(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Sfixed64114(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64Sint32115(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Sint64116(populateLongMap(longProvider));
builder.putAllFieldMapSfixed64String117(populateLongMap(stringProvider));
builder.putAllFieldMapSfixed64Uint32118(populateLongMap(integerProvider));
builder.putAllFieldMapSfixed64Uint64119(populateLongMap(longProvider));
builder.putAllFieldMapSint32Bool120(populateIntegerMap(booleanProvider));
builder.putAllFieldMapSint32Bytes121(populateIntegerMap(bytesProvider));
builder.putAllFieldMapSint32Double122(populateIntegerMap(doubleProvider));
builder.putAllFieldMapSint32Enum123(populateIntegerMap(enumProvider));
builder.putAllFieldMapSint32Fixed32124(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Fixed64125(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Float126(populateIntegerMap(floatProvider));
builder.putAllFieldMapSint32Int32127(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Int64128(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Message129(populateIntegerMap(messageProvider));
builder.putAllFieldMapSint32Sfixed32130(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Sfixed64131(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32Sint32132(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Sint64133(populateIntegerMap(longProvider));
builder.putAllFieldMapSint32String134(populateIntegerMap(stringProvider));
builder.putAllFieldMapSint32Uint32135(populateIntegerMap(integerProvider));
builder.putAllFieldMapSint32Uint64136(populateIntegerMap(longProvider));
builder.putAllFieldMapSint64Bool137(populateLongMap(booleanProvider));
builder.putAllFieldMapSint64Bytes138(populateLongMap(bytesProvider));
builder.putAllFieldMapSint64Double139(populateLongMap(doubleProvider));
builder.putAllFieldMapSint64Enum140(populateLongMap(enumProvider));
builder.putAllFieldMapSint64Fixed32141(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Fixed64142(populateLongMap(longProvider));
builder.putAllFieldMapSint64Float143(populateLongMap(floatProvider));
builder.putAllFieldMapSint64Int32144(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Int64145(populateLongMap(longProvider));
builder.putAllFieldMapSint64Message146(populateLongMap(messageProvider));
builder.putAllFieldMapSint64Sfixed32147(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Sfixed64148(populateLongMap(longProvider));
builder.putAllFieldMapSint64Sint32149(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Sint64150(populateLongMap(longProvider));
builder.putAllFieldMapSint64String151(populateLongMap(stringProvider));
builder.putAllFieldMapSint64Uint32152(populateLongMap(integerProvider));
builder.putAllFieldMapSint64Uint64153(populateLongMap(longProvider));
builder.putAllFieldMapStringBool154(populateStringMap(booleanProvider));
builder.putAllFieldMapStringBytes155(populateStringMap(bytesProvider));
builder.putAllFieldMapStringDouble156(populateStringMap(doubleProvider));
builder.putAllFieldMapStringEnum157(populateStringMap(enumProvider));
builder.putAllFieldMapStringFixed32158(populateStringMap(integerProvider));
builder.putAllFieldMapStringFixed64159(populateStringMap(longProvider));
builder.putAllFieldMapStringFloat160(populateStringMap(floatProvider));
builder.putAllFieldMapStringInt32161(populateStringMap(integerProvider));
builder.putAllFieldMapStringInt64162(populateStringMap(longProvider));
builder.putAllFieldMapStringMessage163(populateStringMap(messageProvider));
builder.putAllFieldMapStringSfixed32164(populateStringMap(integerProvider));
builder.putAllFieldMapStringSfixed64165(populateStringMap(longProvider));
builder.putAllFieldMapStringSint32166(populateStringMap(integerProvider));
builder.putAllFieldMapStringSint64167(populateStringMap(longProvider));
builder.putAllFieldMapStringString168(populateStringMap(stringProvider));
builder.putAllFieldMapStringUint32169(populateStringMap(integerProvider));
builder.putAllFieldMapStringUint64170(populateStringMap(longProvider));
builder.putAllFieldMapUint32Bool171(populateIntegerMap(booleanProvider));
builder.putAllFieldMapUint32Bytes172(populateIntegerMap(bytesProvider));
builder.putAllFieldMapUint32Double173(populateIntegerMap(doubleProvider));
builder.putAllFieldMapUint32Enum174(populateIntegerMap(enumProvider));
builder.putAllFieldMapUint32Fixed32175(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Fixed64176(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Float177(populateIntegerMap(floatProvider));
builder.putAllFieldMapUint32Int32178(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Int64179(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Message180(populateIntegerMap(messageProvider));
builder.putAllFieldMapUint32Sfixed32181(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Sfixed64182(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32Sint32183(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Sint64184(populateIntegerMap(longProvider));
builder.putAllFieldMapUint32String185(populateIntegerMap(stringProvider));
builder.putAllFieldMapUint32Uint32186(populateIntegerMap(integerProvider));
builder.putAllFieldMapUint32Uint64187(populateIntegerMap(longProvider));
builder.putAllFieldMapUint64Bool188(populateLongMap(booleanProvider));
builder.putAllFieldMapUint64Bytes189(populateLongMap(bytesProvider));
builder.putAllFieldMapUint64Double190(populateLongMap(doubleProvider));
builder.putAllFieldMapUint64Enum191(populateLongMap(enumProvider));
builder.putAllFieldMapUint64Fixed32192(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Fixed64193(populateLongMap(longProvider));
builder.putAllFieldMapUint64Float194(populateLongMap(floatProvider));
builder.putAllFieldMapUint64Int32195(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Int64196(populateLongMap(longProvider));
builder.putAllFieldMapUint64Message197(populateLongMap(messageProvider));
builder.putAllFieldMapUint64Sfixed32198(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Sfixed64199(populateLongMap(longProvider));
builder.putAllFieldMapUint64Sint32200(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Sint64201(populateLongMap(longProvider));
builder.putAllFieldMapUint64String202(populateLongMap(stringProvider));
builder.putAllFieldMapUint64Uint32203(populateLongMap(integerProvider));
builder.putAllFieldMapUint64Uint64204(populateLongMap(longProvider));
return builder.build();
}
}

Some files were not shown because too many files have changed in this diff Show More