Merge from Google internal for 3.4 release
This commit is contained in:
parent
9053033a50
commit
09354db143
@ -713,7 +713,6 @@ python_EXTRA_DIST= \
|
||||
python/google/protobuf/internal/packed_field_test.proto \
|
||||
python/google/protobuf/internal/proto_builder_test.py \
|
||||
python/google/protobuf/internal/python_message.py \
|
||||
python/google/protobuf/internal/python_protobuf.cc \
|
||||
python/google/protobuf/internal/reflection_test.py \
|
||||
python/google/protobuf/internal/service_reflection_test.py \
|
||||
python/google/protobuf/internal/symbol_database_test.py \
|
||||
@ -762,7 +761,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/python_protobuf.h \
|
||||
python/google/protobuf/reflection.py \
|
||||
python/google/protobuf/service.py \
|
||||
python/google/protobuf/service_reflection.py \
|
||||
|
@ -36,7 +36,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\parser.h" in
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_generator.h" include\google\protobuf\compiler\php\php_generator.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h" include\google\protobuf\compiler\plugin.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\profile.pb.h" include\google\protobuf\compiler\profile.pb.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h" include\google\protobuf\compiler\python\python_generator.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h
|
||||
@ -50,6 +49,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\field_mask.pb.h" incl
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_reflection.h" include\google\protobuf\generated_enum_reflection.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_enum_util.h" include\google\protobuf\generated_enum_util.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_reflection.h" include\google\protobuf\generated_message_reflection.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_table_driven.h" include\google\protobuf\generated_message_table_driven.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_util.h" include\google\protobuf\generated_message_util.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\has_bits.h" include\google\protobuf\has_bits.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h
|
||||
@ -70,6 +70,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\map_type_handler.h" i
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message.h" include\google\protobuf\message.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\message_lite.h" include\google\protobuf\message_lite.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata.h" include\google\protobuf\metadata.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\metadata_lite.h" include\google\protobuf\metadata_lite.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection.h" include\google\protobuf\reflection.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\reflection_ops.h" include\google\protobuf\reflection_ops.h
|
||||
copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\repeated_field.h" include\google\protobuf\repeated_field.h
|
||||
|
@ -88,7 +88,6 @@ set(libprotoc_files
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/plugin.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/profile.pb.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc
|
||||
|
@ -123,6 +123,7 @@ set(tests_files
|
||||
${protobuf_source_dir}/src/google/protobuf/arenastring_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/command_line_interface_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_move_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/cpp_unittest.cc
|
||||
${protobuf_source_dir}/src/google/protobuf/compiler/cpp/metadata_test.cc
|
||||
|
@ -1516,9 +1516,10 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner,
|
||||
"BytesField", REQUIRED,
|
||||
R"({"optionalBytes": "AQI="})",
|
||||
R"(optional_bytes: "\x01\x02")");
|
||||
ExpectParseFailureForJson(
|
||||
"BytesFieldInvalidBase64Characters", REQUIRED,
|
||||
R"({"optionalBytes": "-_=="})");
|
||||
RunValidJsonTest(
|
||||
"BytesFieldBase64Url", RECOMMENDED,
|
||||
R"({"optionalBytes": "-_"})",
|
||||
R"(optional_bytes: "\xfb")");
|
||||
|
||||
// Message fields.
|
||||
RunValidJsonTest(
|
||||
|
@ -12,6 +12,8 @@ Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
|
||||
Recommended.FieldMaskTooManyUnderscore.JsonOutput
|
||||
Recommended.JsonInput.BoolFieldDoubleQuotedFalse
|
||||
Recommended.JsonInput.BoolFieldDoubleQuotedTrue
|
||||
Recommended.JsonInput.BytesFieldBase64Url.JsonOutput
|
||||
Recommended.JsonInput.BytesFieldBase64Url.ProtobufOutput
|
||||
Recommended.JsonInput.FieldMaskInvalidCharacter
|
||||
Recommended.JsonInput.FieldNameDuplicate
|
||||
Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
|
||||
|
@ -1,17 +1,616 @@
|
||||
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
|
||||
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
|
||||
Recommended.FieldMaskTooManyUnderscore.JsonOutput
|
||||
Recommended.JsonInput.BoolFieldAllCapitalFalse
|
||||
Recommended.JsonInput.BoolFieldAllCapitalTrue
|
||||
Recommended.JsonInput.BoolFieldCamelCaseFalse
|
||||
Recommended.JsonInput.BoolFieldCamelCaseTrue
|
||||
Recommended.JsonInput.BoolFieldDoubleQuotedFalse
|
||||
Recommended.JsonInput.BoolFieldDoubleQuotedTrue
|
||||
Recommended.JsonInput.BoolFieldIntegerOne
|
||||
Recommended.JsonInput.BoolFieldIntegerZero
|
||||
Recommended.JsonInput.BoolMapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.BytesFieldBase64Url.JsonOutput
|
||||
Recommended.JsonInput.BytesFieldBase64Url.ProtobufOutput
|
||||
Recommended.JsonInput.DoubleFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.DoubleFieldNanNotQuoted
|
||||
Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
|
||||
Recommended.JsonInput.DurationHas3FractionalDigits.Validator
|
||||
Recommended.JsonInput.DurationHas6FractionalDigits.Validator
|
||||
Recommended.JsonInput.DurationHas9FractionalDigits.Validator
|
||||
Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
|
||||
Recommended.JsonInput.FieldMaskInvalidCharacter
|
||||
Recommended.JsonInput.FieldNameDuplicate
|
||||
Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
|
||||
Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
|
||||
Recommended.JsonInput.FieldNameNotQuoted
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
|
||||
Recommended.JsonInput.FloatFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNanNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
|
||||
Required.JsonInput.BytesFieldInvalidBase64Characters
|
||||
Recommended.JsonInput.Int32MapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.Int64FieldBeString.Validator
|
||||
Recommended.JsonInput.Int64MapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.JsonWithComments
|
||||
Recommended.JsonInput.MapFieldKeyIsNull
|
||||
Recommended.JsonInput.MapFieldValueIsNull
|
||||
Recommended.JsonInput.MissingCommaMultiline
|
||||
Recommended.JsonInput.MissingCommaOneLine
|
||||
Recommended.JsonInput.MultilineNoSpaces.JsonOutput
|
||||
Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput
|
||||
Recommended.JsonInput.MultilineWithSpaces.JsonOutput
|
||||
Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput
|
||||
Recommended.JsonInput.OneLineNoSpaces.JsonOutput
|
||||
Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput
|
||||
Recommended.JsonInput.OneLineWithSpaces.JsonOutput
|
||||
Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroBool.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroBool.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroBytes.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroDouble.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroEnum.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroEnum.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroFloat.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroMessage.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroMessage.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroString.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroString.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroUint32.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroUint64.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
|
||||
Recommended.JsonInput.RepeatedFieldMessageElementIsNull
|
||||
Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
|
||||
Recommended.JsonInput.RepeatedFieldTrailingComma
|
||||
Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines
|
||||
Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace
|
||||
Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
|
||||
Recommended.JsonInput.StringEndsWithEscapeChar
|
||||
Recommended.JsonInput.StringFieldInvalidEscape
|
||||
Recommended.JsonInput.StringFieldSingleQuoteBoth
|
||||
Recommended.JsonInput.StringFieldSingleQuoteKey
|
||||
Recommended.JsonInput.StringFieldSingleQuoteValue
|
||||
Recommended.JsonInput.StringFieldSurrogateInWrongOrder
|
||||
Recommended.JsonInput.StringFieldUnpairedHighSurrogate
|
||||
Recommended.JsonInput.StringFieldUnpairedLowSurrogate
|
||||
Recommended.JsonInput.StringFieldUnterminatedEscape
|
||||
Recommended.JsonInput.StringFieldUppercaseEscapeLetter
|
||||
Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
|
||||
Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
|
||||
Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
|
||||
Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
|
||||
Recommended.JsonInput.TimestampZeroNormalized.Validator
|
||||
Recommended.JsonInput.TrailingCommaInAnObject
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
|
||||
Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.Uint64FieldBeString.Validator
|
||||
Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
|
||||
Recommended.ProtobufInput.OneofZeroBool.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroDouble.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroEnum.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroFloat.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroMessage.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroString.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroUint32.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroUint64.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput
|
||||
Required.DurationProtoInputTooLarge.JsonOutput
|
||||
Required.DurationProtoInputTooSmall.JsonOutput
|
||||
Required.JsonInput.AllFieldAcceptNull.JsonOutput
|
||||
Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
|
||||
Required.JsonInput.Any.JsonOutput
|
||||
Required.JsonInput.Any.ProtobufOutput
|
||||
Required.JsonInput.AnyNested.JsonOutput
|
||||
Required.JsonInput.AnyNested.ProtobufOutput
|
||||
Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
|
||||
Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
|
||||
Required.JsonInput.AnyWithDuration.JsonOutput
|
||||
Required.JsonInput.AnyWithDuration.ProtobufOutput
|
||||
Required.JsonInput.AnyWithFieldMask.JsonOutput
|
||||
Required.JsonInput.AnyWithFieldMask.ProtobufOutput
|
||||
Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
|
||||
Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
|
||||
Required.JsonInput.AnyWithStruct.JsonOutput
|
||||
Required.JsonInput.AnyWithStruct.ProtobufOutput
|
||||
Required.JsonInput.AnyWithTimestamp.JsonOutput
|
||||
Required.JsonInput.AnyWithTimestamp.ProtobufOutput
|
||||
Required.JsonInput.AnyWithValueForInteger.JsonOutput
|
||||
Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
|
||||
Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
|
||||
Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
|
||||
Required.JsonInput.BoolFieldFalse.JsonOutput
|
||||
Required.JsonInput.BoolFieldFalse.ProtobufOutput
|
||||
Required.JsonInput.BoolFieldTrue.JsonOutput
|
||||
Required.JsonInput.BoolFieldTrue.ProtobufOutput
|
||||
Required.JsonInput.BoolMapEscapedKey.JsonOutput
|
||||
Required.JsonInput.BoolMapEscapedKey.ProtobufOutput
|
||||
Required.JsonInput.BoolMapField.JsonOutput
|
||||
Required.JsonInput.BoolMapField.ProtobufOutput
|
||||
Required.JsonInput.BytesField.JsonOutput
|
||||
Required.JsonInput.BytesField.ProtobufOutput
|
||||
Required.JsonInput.BytesRepeatedField.JsonOutput
|
||||
Required.JsonInput.BytesRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldInfinity.JsonOutput
|
||||
Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldNan.JsonOutput
|
||||
Required.JsonInput.DoubleFieldNan.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
|
||||
Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldTooLarge
|
||||
Required.JsonInput.DoubleFieldTooSmall
|
||||
Required.JsonInput.DurationJsonInputTooLarge
|
||||
Required.JsonInput.DurationJsonInputTooSmall
|
||||
Required.JsonInput.DurationMaxValue.JsonOutput
|
||||
Required.JsonInput.DurationMaxValue.ProtobufOutput
|
||||
Required.JsonInput.DurationMinValue.JsonOutput
|
||||
Required.JsonInput.DurationMinValue.ProtobufOutput
|
||||
Required.JsonInput.DurationMissingS
|
||||
Required.JsonInput.DurationRepeatedValue.JsonOutput
|
||||
Required.JsonInput.DurationRepeatedValue.ProtobufOutput
|
||||
Required.JsonInput.EnumField.JsonOutput
|
||||
Required.JsonInput.EnumField.ProtobufOutput
|
||||
Required.JsonInput.EnumFieldNotQuoted
|
||||
Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
|
||||
Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
|
||||
Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
|
||||
Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
|
||||
Required.JsonInput.EnumFieldUnknownValue.Validator
|
||||
Required.JsonInput.EnumRepeatedField.JsonOutput
|
||||
Required.JsonInput.EnumRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.FieldMask.JsonOutput
|
||||
Required.JsonInput.FieldMask.ProtobufOutput
|
||||
Required.JsonInput.FieldNameEscaped.JsonOutput
|
||||
Required.JsonInput.FieldNameEscaped.ProtobufOutput
|
||||
Required.JsonInput.FieldNameInLowerCamelCase.Validator
|
||||
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
|
||||
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
|
||||
Required.JsonInput.FieldNameWithMixedCases.JsonOutput
|
||||
Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
|
||||
Required.JsonInput.FieldNameWithMixedCases.Validator
|
||||
Required.JsonInput.FieldNameWithNumbers.JsonOutput
|
||||
Required.JsonInput.FieldNameWithNumbers.ProtobufOutput
|
||||
Required.JsonInput.FieldNameWithNumbers.Validator
|
||||
Required.JsonInput.FloatFieldInfinity.JsonOutput
|
||||
Required.JsonInput.FloatFieldInfinity.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldNan.JsonOutput
|
||||
Required.JsonInput.FloatFieldNan.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
|
||||
Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldQuotedValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldTooLarge
|
||||
Required.JsonInput.FloatFieldTooSmall
|
||||
Required.JsonInput.HelloWorld.JsonOutput
|
||||
Required.JsonInput.HelloWorld.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
|
||||
Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
|
||||
Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldLeadingSpace
|
||||
Required.JsonInput.Int32FieldLeadingZero
|
||||
Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldMaxValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldMaxValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldMinValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldMinValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldNegativeWithLeadingZero
|
||||
Required.JsonInput.Int32FieldNotInteger
|
||||
Required.JsonInput.Int32FieldNotNumber
|
||||
Required.JsonInput.Int32FieldPlusSign
|
||||
Required.JsonInput.Int32FieldStringValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldStringValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
|
||||
Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldTooLarge
|
||||
Required.JsonInput.Int32FieldTooSmall
|
||||
Required.JsonInput.Int32FieldTrailingSpace
|
||||
Required.JsonInput.Int32MapEscapedKey.JsonOutput
|
||||
Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
|
||||
Required.JsonInput.Int32MapField.JsonOutput
|
||||
Required.JsonInput.Int32MapField.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldMaxValue.JsonOutput
|
||||
Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
|
||||
Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldMinValue.JsonOutput
|
||||
Required.JsonInput.Int64FieldMinValue.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
|
||||
Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldNotInteger
|
||||
Required.JsonInput.Int64FieldNotNumber
|
||||
Required.JsonInput.Int64FieldTooLarge
|
||||
Required.JsonInput.Int64FieldTooSmall
|
||||
Required.JsonInput.Int64MapEscapedKey.JsonOutput
|
||||
Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
|
||||
Required.JsonInput.Int64MapField.JsonOutput
|
||||
Required.JsonInput.Int64MapField.ProtobufOutput
|
||||
Required.JsonInput.MessageField.JsonOutput
|
||||
Required.JsonInput.MessageField.ProtobufOutput
|
||||
Required.JsonInput.MessageMapField.JsonOutput
|
||||
Required.JsonInput.MessageMapField.ProtobufOutput
|
||||
Required.JsonInput.MessageRepeatedField.JsonOutput
|
||||
Required.JsonInput.MessageRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.OneofFieldDuplicate
|
||||
Required.JsonInput.OptionalBoolWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalBytesWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalDoubleWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalFloatWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalInt32Wrapper.JsonOutput
|
||||
Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalInt64Wrapper.JsonOutput
|
||||
Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalStringWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalStringWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalUint32Wrapper.JsonOutput
|
||||
Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalUint64Wrapper.JsonOutput
|
||||
Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
|
||||
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
|
||||
Required.JsonInput.OriginalProtoFieldName.JsonOutput
|
||||
Required.JsonInput.OriginalProtoFieldName.ProtobufOutput
|
||||
Required.JsonInput.PrimitiveRepeatedField.JsonOutput
|
||||
Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.RepeatedBoolWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedBytesWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage
|
||||
Required.JsonInput.RepeatedFloatWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedStringWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
|
||||
Required.JsonInput.StringField.JsonOutput
|
||||
Required.JsonInput.StringField.ProtobufOutput
|
||||
Required.JsonInput.StringFieldEscape.JsonOutput
|
||||
Required.JsonInput.StringFieldEscape.ProtobufOutput
|
||||
Required.JsonInput.StringFieldNotAString
|
||||
Required.JsonInput.StringFieldSurrogatePair.JsonOutput
|
||||
Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
|
||||
Required.JsonInput.StringFieldUnicode.JsonOutput
|
||||
Required.JsonInput.StringFieldUnicode.ProtobufOutput
|
||||
Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
|
||||
Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
|
||||
Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
|
||||
Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
|
||||
Required.JsonInput.StringRepeatedField.JsonOutput
|
||||
Required.JsonInput.StringRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.Struct.JsonOutput
|
||||
Required.JsonInput.Struct.ProtobufOutput
|
||||
Required.JsonInput.TimestampJsonInputLowercaseT
|
||||
Required.JsonInput.TimestampJsonInputLowercaseZ
|
||||
Required.JsonInput.TimestampJsonInputMissingT
|
||||
Required.JsonInput.TimestampJsonInputMissingZ
|
||||
Required.JsonInput.TimestampJsonInputTooLarge
|
||||
Required.JsonInput.TimestampJsonInputTooSmall
|
||||
Required.JsonInput.TimestampMaxValue.JsonOutput
|
||||
Required.JsonInput.TimestampMaxValue.ProtobufOutput
|
||||
Required.JsonInput.TimestampMinValue.JsonOutput
|
||||
Required.JsonInput.TimestampMinValue.ProtobufOutput
|
||||
Required.JsonInput.TimestampRepeatedValue.JsonOutput
|
||||
Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
|
||||
Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
|
||||
Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
|
||||
Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
|
||||
Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
|
||||
Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
|
||||
Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
|
||||
Required.JsonInput.Uint32FieldMaxValue.JsonOutput
|
||||
Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput
|
||||
Required.JsonInput.Uint32FieldNotInteger
|
||||
Required.JsonInput.Uint32FieldNotNumber
|
||||
Required.JsonInput.Uint32FieldTooLarge
|
||||
Required.JsonInput.Uint32MapField.JsonOutput
|
||||
Required.JsonInput.Uint32MapField.ProtobufOutput
|
||||
Required.JsonInput.Uint64FieldMaxValue.JsonOutput
|
||||
Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
|
||||
Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
|
||||
Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
|
||||
Required.JsonInput.Uint64FieldNotInteger
|
||||
Required.JsonInput.Uint64FieldNotNumber
|
||||
Required.JsonInput.Uint64FieldTooLarge
|
||||
Required.JsonInput.Uint64MapField.JsonOutput
|
||||
Required.JsonInput.Uint64MapField.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptBool.JsonOutput
|
||||
Required.JsonInput.ValueAcceptBool.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptFloat.JsonOutput
|
||||
Required.JsonInput.ValueAcceptFloat.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptInteger.JsonOutput
|
||||
Required.JsonInput.ValueAcceptInteger.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptList.JsonOutput
|
||||
Required.JsonInput.ValueAcceptList.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptNull.JsonOutput
|
||||
Required.JsonInput.ValueAcceptNull.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptObject.JsonOutput
|
||||
Required.JsonInput.ValueAcceptObject.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptString.JsonOutput
|
||||
Required.JsonInput.ValueAcceptString.ProtobufOutput
|
||||
Required.JsonInput.WrapperTypesWithNullValue.JsonOutput
|
||||
Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
|
||||
Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
|
||||
Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
|
||||
Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
|
||||
Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
|
||||
Required.ProtobufInput.IllegalZeroFieldNum_Case_0
|
||||
Required.ProtobufInput.IllegalZeroFieldNum_Case_1
|
||||
Required.ProtobufInput.IllegalZeroFieldNum_Case_2
|
||||
Required.ProtobufInput.IllegalZeroFieldNum_Case_3
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInPackedField.BOOL
|
||||
Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInPackedField.ENUM
|
||||
Required.ProtobufInput.PrematureEofInPackedField.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInPackedField.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInPackedField.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInPackedField.INT32
|
||||
Required.ProtobufInput.PrematureEofInPackedField.INT64
|
||||
Required.ProtobufInput.PrematureEofInPackedField.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInPackedField.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInPackedField.SINT32
|
||||
Required.ProtobufInput.PrematureEofInPackedField.SINT64
|
||||
Required.ProtobufInput.PrematureEofInPackedField.UINT32
|
||||
Required.ProtobufInput.PrematureEofInPackedField.UINT64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput
|
||||
Required.TimestampProtoInputTooLarge.JsonOutput
|
||||
Required.TimestampProtoInputTooSmall.JsonOutput
|
||||
|
@ -7,21 +7,462 @@
|
||||
# TODO(haberman): insert links to corresponding bugs tracking the issue.
|
||||
# Should we use GitHub issues or the Google-internal bug tracker?
|
||||
|
||||
Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput
|
||||
Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
|
||||
Recommended.FieldMaskTooManyUnderscore.JsonOutput
|
||||
Recommended.JsonInput.BoolFieldAllCapitalFalse
|
||||
Recommended.JsonInput.BoolFieldAllCapitalTrue
|
||||
Recommended.JsonInput.BoolFieldCamelCaseFalse
|
||||
Recommended.JsonInput.BoolFieldCamelCaseTrue
|
||||
Recommended.JsonInput.BoolFieldDoubleQuotedFalse
|
||||
Recommended.JsonInput.BoolFieldDoubleQuotedTrue
|
||||
Recommended.JsonInput.BoolFieldIntegerOne
|
||||
Recommended.JsonInput.BoolFieldIntegerZero
|
||||
Recommended.JsonInput.BoolMapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.BytesFieldBase64Url.JsonOutput
|
||||
Recommended.JsonInput.BytesFieldBase64Url.ProtobufOutput
|
||||
Recommended.JsonInput.DoubleFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.DoubleFieldNanNotQuoted
|
||||
Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted
|
||||
Recommended.JsonInput.DurationHas3FractionalDigits.Validator
|
||||
Recommended.JsonInput.DurationHas6FractionalDigits.Validator
|
||||
Recommended.JsonInput.DurationHas9FractionalDigits.Validator
|
||||
Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator
|
||||
Recommended.JsonInput.FieldMaskInvalidCharacter
|
||||
Recommended.JsonInput.FieldNameDuplicate
|
||||
Recommended.JsonInput.FieldNameDuplicateDifferentCasing1
|
||||
Recommended.JsonInput.FieldNameDuplicateDifferentCasing2
|
||||
Recommended.JsonInput.FieldNameNotQuoted
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput
|
||||
Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator
|
||||
Recommended.JsonInput.FloatFieldInfinityNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNanNotQuoted
|
||||
Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted
|
||||
Required.JsonInput.BytesFieldInvalidBase64Characters
|
||||
Recommended.JsonInput.Int32MapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.Int64FieldBeString.Validator
|
||||
Recommended.JsonInput.Int64MapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.JsonWithComments
|
||||
Recommended.JsonInput.MapFieldKeyIsNull
|
||||
Recommended.JsonInput.MapFieldValueIsNull
|
||||
Recommended.JsonInput.MissingCommaMultiline
|
||||
Recommended.JsonInput.MissingCommaOneLine
|
||||
Recommended.JsonInput.MultilineNoSpaces.JsonOutput
|
||||
Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput
|
||||
Recommended.JsonInput.MultilineWithSpaces.JsonOutput
|
||||
Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput
|
||||
Recommended.JsonInput.OneLineNoSpaces.JsonOutput
|
||||
Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput
|
||||
Recommended.JsonInput.OneLineWithSpaces.JsonOutput
|
||||
Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroBool.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroBool.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroBytes.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroBytes.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroDouble.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroDouble.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroEnum.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroEnum.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroFloat.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroFloat.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroMessage.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroMessage.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroString.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroString.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroUint32.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroUint32.ProtobufOutput
|
||||
Recommended.JsonInput.OneofZeroUint64.JsonOutput
|
||||
Recommended.JsonInput.OneofZeroUint64.ProtobufOutput
|
||||
Recommended.JsonInput.RepeatedFieldMessageElementIsNull
|
||||
Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull
|
||||
Recommended.JsonInput.RepeatedFieldTrailingComma
|
||||
Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines
|
||||
Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace
|
||||
Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace
|
||||
Recommended.JsonInput.StringEndsWithEscapeChar
|
||||
Recommended.JsonInput.StringFieldInvalidEscape
|
||||
Recommended.JsonInput.StringFieldSingleQuoteBoth
|
||||
Recommended.JsonInput.StringFieldSingleQuoteKey
|
||||
Recommended.JsonInput.StringFieldSingleQuoteValue
|
||||
Recommended.JsonInput.StringFieldSurrogateInWrongOrder
|
||||
Recommended.JsonInput.StringFieldUnpairedHighSurrogate
|
||||
Recommended.JsonInput.StringFieldUnpairedLowSurrogate
|
||||
Recommended.JsonInput.StringFieldUnterminatedEscape
|
||||
Recommended.JsonInput.StringFieldUppercaseEscapeLetter
|
||||
Recommended.JsonInput.TimestampHas3FractionalDigits.Validator
|
||||
Recommended.JsonInput.TimestampHas6FractionalDigits.Validator
|
||||
Recommended.JsonInput.TimestampHas9FractionalDigits.Validator
|
||||
Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator
|
||||
Recommended.JsonInput.TimestampZeroNormalized.Validator
|
||||
Recommended.JsonInput.TrailingCommaInAnObject
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithSpace
|
||||
Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace
|
||||
Recommended.JsonInput.Uint32MapFieldKeyNotQuoted
|
||||
Recommended.JsonInput.Uint64FieldBeString.Validator
|
||||
Recommended.JsonInput.Uint64MapFieldKeyNotQuoted
|
||||
Recommended.ProtobufInput.OneofZeroBool.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroBytes.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroDouble.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroEnum.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroFloat.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroMessage.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroString.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroString.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroUint32.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput
|
||||
Recommended.ProtobufInput.OneofZeroUint64.JsonOutput
|
||||
Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput
|
||||
Required.DurationProtoInputTooLarge.JsonOutput
|
||||
Required.DurationProtoInputTooSmall.JsonOutput
|
||||
Required.JsonInput.AllFieldAcceptNull.JsonOutput
|
||||
Required.JsonInput.AllFieldAcceptNull.ProtobufOutput
|
||||
Required.JsonInput.Any.JsonOutput
|
||||
Required.JsonInput.Any.ProtobufOutput
|
||||
Required.JsonInput.AnyNested.JsonOutput
|
||||
Required.JsonInput.AnyNested.ProtobufOutput
|
||||
Required.JsonInput.AnyUnorderedTypeTag.JsonOutput
|
||||
Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput
|
||||
Required.JsonInput.AnyWithDuration.JsonOutput
|
||||
Required.JsonInput.AnyWithDuration.ProtobufOutput
|
||||
Required.JsonInput.AnyWithFieldMask.JsonOutput
|
||||
Required.JsonInput.AnyWithFieldMask.ProtobufOutput
|
||||
Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput
|
||||
Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput
|
||||
Required.JsonInput.AnyWithStruct.JsonOutput
|
||||
Required.JsonInput.AnyWithStruct.ProtobufOutput
|
||||
Required.JsonInput.AnyWithTimestamp.JsonOutput
|
||||
Required.JsonInput.AnyWithTimestamp.ProtobufOutput
|
||||
Required.JsonInput.AnyWithValueForInteger.JsonOutput
|
||||
Required.JsonInput.AnyWithValueForInteger.ProtobufOutput
|
||||
Required.JsonInput.AnyWithValueForJsonObject.JsonOutput
|
||||
Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput
|
||||
Required.JsonInput.BoolFieldFalse.JsonOutput
|
||||
Required.JsonInput.BoolFieldFalse.ProtobufOutput
|
||||
Required.JsonInput.BoolFieldTrue.JsonOutput
|
||||
Required.JsonInput.BoolFieldTrue.ProtobufOutput
|
||||
Required.JsonInput.BoolMapEscapedKey.JsonOutput
|
||||
Required.JsonInput.BoolMapEscapedKey.ProtobufOutput
|
||||
Required.JsonInput.BoolMapField.JsonOutput
|
||||
Required.JsonInput.BoolMapField.ProtobufOutput
|
||||
Required.JsonInput.BytesField.JsonOutput
|
||||
Required.JsonInput.BytesField.ProtobufOutput
|
||||
Required.JsonInput.BytesRepeatedField.JsonOutput
|
||||
Required.JsonInput.BytesRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldInfinity.JsonOutput
|
||||
Required.JsonInput.DoubleFieldInfinity.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldNan.JsonOutput
|
||||
Required.JsonInput.DoubleFieldNan.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput
|
||||
Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldQuotedValue.JsonOutput
|
||||
Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput
|
||||
Required.JsonInput.DoubleFieldTooLarge
|
||||
Required.JsonInput.DoubleFieldTooSmall
|
||||
Required.JsonInput.DurationJsonInputTooLarge
|
||||
Required.JsonInput.DurationJsonInputTooSmall
|
||||
Required.JsonInput.DurationMaxValue.JsonOutput
|
||||
Required.JsonInput.DurationMaxValue.ProtobufOutput
|
||||
Required.JsonInput.DurationMinValue.JsonOutput
|
||||
Required.JsonInput.DurationMinValue.ProtobufOutput
|
||||
Required.JsonInput.DurationMissingS
|
||||
Required.JsonInput.DurationRepeatedValue.JsonOutput
|
||||
Required.JsonInput.DurationRepeatedValue.ProtobufOutput
|
||||
Required.JsonInput.EnumField.JsonOutput
|
||||
Required.JsonInput.EnumField.ProtobufOutput
|
||||
Required.JsonInput.EnumFieldNotQuoted
|
||||
Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput
|
||||
Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput
|
||||
Required.JsonInput.EnumFieldNumericValueZero.JsonOutput
|
||||
Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput
|
||||
Required.JsonInput.EnumFieldUnknownValue.Validator
|
||||
Required.JsonInput.EnumRepeatedField.JsonOutput
|
||||
Required.JsonInput.EnumRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.FieldMask.JsonOutput
|
||||
Required.JsonInput.FieldMask.ProtobufOutput
|
||||
Required.JsonInput.FieldNameEscaped.JsonOutput
|
||||
Required.JsonInput.FieldNameEscaped.ProtobufOutput
|
||||
Required.JsonInput.FieldNameInLowerCamelCase.Validator
|
||||
Required.JsonInput.FieldNameInSnakeCase.JsonOutput
|
||||
Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput
|
||||
Required.JsonInput.FieldNameWithMixedCases.JsonOutput
|
||||
Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput
|
||||
Required.JsonInput.FieldNameWithMixedCases.Validator
|
||||
Required.JsonInput.FieldNameWithNumbers.JsonOutput
|
||||
Required.JsonInput.FieldNameWithNumbers.ProtobufOutput
|
||||
Required.JsonInput.FieldNameWithNumbers.Validator
|
||||
Required.JsonInput.FloatFieldInfinity.JsonOutput
|
||||
Required.JsonInput.FloatFieldInfinity.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldNan.JsonOutput
|
||||
Required.JsonInput.FloatFieldNan.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput
|
||||
Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldQuotedValue.JsonOutput
|
||||
Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput
|
||||
Required.JsonInput.FloatFieldTooLarge
|
||||
Required.JsonInput.FloatFieldTooSmall
|
||||
Required.JsonInput.HelloWorld.JsonOutput
|
||||
Required.JsonInput.HelloWorld.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldExponentialFormat.JsonOutput
|
||||
Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput
|
||||
Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldLeadingSpace
|
||||
Required.JsonInput.Int32FieldLeadingZero
|
||||
Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldMaxValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldMaxValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldMinFloatValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldMinValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldMinValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldNegativeWithLeadingZero
|
||||
Required.JsonInput.Int32FieldNotInteger
|
||||
Required.JsonInput.Int32FieldNotNumber
|
||||
Required.JsonInput.Int32FieldPlusSign
|
||||
Required.JsonInput.Int32FieldStringValue.JsonOutput
|
||||
Required.JsonInput.Int32FieldStringValue.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput
|
||||
Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput
|
||||
Required.JsonInput.Int32FieldTooLarge
|
||||
Required.JsonInput.Int32FieldTooSmall
|
||||
Required.JsonInput.Int32FieldTrailingSpace
|
||||
Required.JsonInput.Int32MapEscapedKey.JsonOutput
|
||||
Required.JsonInput.Int32MapEscapedKey.ProtobufOutput
|
||||
Required.JsonInput.Int32MapField.JsonOutput
|
||||
Required.JsonInput.Int32MapField.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldMaxValue.JsonOutput
|
||||
Required.JsonInput.Int64FieldMaxValue.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput
|
||||
Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldMinValue.JsonOutput
|
||||
Required.JsonInput.Int64FieldMinValue.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput
|
||||
Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput
|
||||
Required.JsonInput.Int64FieldNotInteger
|
||||
Required.JsonInput.Int64FieldNotNumber
|
||||
Required.JsonInput.Int64FieldTooLarge
|
||||
Required.JsonInput.Int64FieldTooSmall
|
||||
Required.JsonInput.Int64MapEscapedKey.JsonOutput
|
||||
Required.JsonInput.Int64MapEscapedKey.ProtobufOutput
|
||||
Required.JsonInput.Int64MapField.JsonOutput
|
||||
Required.JsonInput.Int64MapField.ProtobufOutput
|
||||
Required.JsonInput.MessageField.JsonOutput
|
||||
Required.JsonInput.MessageField.ProtobufOutput
|
||||
Required.JsonInput.MessageMapField.JsonOutput
|
||||
Required.JsonInput.MessageMapField.ProtobufOutput
|
||||
Required.JsonInput.MessageRepeatedField.JsonOutput
|
||||
Required.JsonInput.MessageRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.OneofFieldDuplicate
|
||||
Required.JsonInput.OptionalBoolWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalBoolWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalBytesWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalBytesWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalDoubleWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalFloatWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalFloatWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalInt32Wrapper.JsonOutput
|
||||
Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalInt64Wrapper.JsonOutput
|
||||
Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalStringWrapper.JsonOutput
|
||||
Required.JsonInput.OptionalStringWrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalUint32Wrapper.JsonOutput
|
||||
Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalUint64Wrapper.JsonOutput
|
||||
Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput
|
||||
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput
|
||||
Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput
|
||||
Required.JsonInput.OriginalProtoFieldName.JsonOutput
|
||||
Required.JsonInput.OriginalProtoFieldName.ProtobufOutput
|
||||
Required.JsonInput.PrimitiveRepeatedField.JsonOutput
|
||||
Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.RepeatedBoolWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedBytesWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedDoubleWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt
|
||||
Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage
|
||||
Required.JsonInput.RepeatedFloatWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedInt32Wrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedInt64Wrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedStringWrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedStringWrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedUint32Wrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput
|
||||
Required.JsonInput.RepeatedUint64Wrapper.JsonOutput
|
||||
Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput
|
||||
Required.JsonInput.StringField.JsonOutput
|
||||
Required.JsonInput.StringField.ProtobufOutput
|
||||
Required.JsonInput.StringFieldEscape.JsonOutput
|
||||
Required.JsonInput.StringFieldEscape.ProtobufOutput
|
||||
Required.JsonInput.StringFieldNotAString
|
||||
Required.JsonInput.StringFieldSurrogatePair.JsonOutput
|
||||
Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput
|
||||
Required.JsonInput.StringFieldUnicode.JsonOutput
|
||||
Required.JsonInput.StringFieldUnicode.ProtobufOutput
|
||||
Required.JsonInput.StringFieldUnicodeEscape.JsonOutput
|
||||
Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput
|
||||
Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput
|
||||
Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput
|
||||
Required.JsonInput.StringRepeatedField.JsonOutput
|
||||
Required.JsonInput.StringRepeatedField.ProtobufOutput
|
||||
Required.JsonInput.Struct.JsonOutput
|
||||
Required.JsonInput.Struct.ProtobufOutput
|
||||
Required.JsonInput.TimestampJsonInputLowercaseT
|
||||
Required.JsonInput.TimestampJsonInputLowercaseZ
|
||||
Required.JsonInput.TimestampJsonInputMissingT
|
||||
Required.JsonInput.TimestampJsonInputMissingZ
|
||||
Required.JsonInput.TimestampJsonInputTooLarge
|
||||
Required.JsonInput.TimestampJsonInputTooSmall
|
||||
Required.JsonInput.TimestampMaxValue.JsonOutput
|
||||
Required.JsonInput.TimestampMaxValue.ProtobufOutput
|
||||
Required.JsonInput.TimestampMinValue.JsonOutput
|
||||
Required.JsonInput.TimestampMinValue.ProtobufOutput
|
||||
Required.JsonInput.TimestampRepeatedValue.JsonOutput
|
||||
Required.JsonInput.TimestampRepeatedValue.ProtobufOutput
|
||||
Required.JsonInput.TimestampWithNegativeOffset.JsonOutput
|
||||
Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput
|
||||
Required.JsonInput.TimestampWithPositiveOffset.JsonOutput
|
||||
Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput
|
||||
Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput
|
||||
Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput
|
||||
Required.JsonInput.Uint32FieldMaxValue.JsonOutput
|
||||
Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput
|
||||
Required.JsonInput.Uint32FieldNotInteger
|
||||
Required.JsonInput.Uint32FieldNotNumber
|
||||
Required.JsonInput.Uint32FieldTooLarge
|
||||
Required.JsonInput.Uint32MapField.JsonOutput
|
||||
Required.JsonInput.Uint32MapField.ProtobufOutput
|
||||
Required.JsonInput.Uint64FieldMaxValue.JsonOutput
|
||||
Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput
|
||||
Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput
|
||||
Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput
|
||||
Required.JsonInput.Uint64FieldNotInteger
|
||||
Required.JsonInput.Uint64FieldNotNumber
|
||||
Required.JsonInput.Uint64FieldTooLarge
|
||||
Required.JsonInput.Uint64MapField.JsonOutput
|
||||
Required.JsonInput.Uint64MapField.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptBool.JsonOutput
|
||||
Required.JsonInput.ValueAcceptBool.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptFloat.JsonOutput
|
||||
Required.JsonInput.ValueAcceptFloat.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptInteger.JsonOutput
|
||||
Required.JsonInput.ValueAcceptInteger.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptList.JsonOutput
|
||||
Required.JsonInput.ValueAcceptList.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptNull.JsonOutput
|
||||
Required.JsonInput.ValueAcceptNull.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptObject.JsonOutput
|
||||
Required.JsonInput.ValueAcceptObject.ProtobufOutput
|
||||
Required.JsonInput.ValueAcceptString.JsonOutput
|
||||
Required.JsonInput.ValueAcceptString.ProtobufOutput
|
||||
Required.JsonInput.WrapperTypesWithNullValue.JsonOutput
|
||||
Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput
|
||||
Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
|
||||
Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
|
||||
Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
|
||||
Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput
|
||||
Required.ProtobufInput.IllegalZeroFieldNum_Case_0
|
||||
Required.ProtobufInput.IllegalZeroFieldNum_Case_1
|
||||
Required.ProtobufInput.IllegalZeroFieldNum_Case_2
|
||||
Required.ProtobufInput.IllegalZeroFieldNum_Case_3
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInPackedField.BOOL
|
||||
Required.ProtobufInput.PrematureEofInPackedField.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInPackedField.ENUM
|
||||
@ -36,3 +477,149 @@ Required.ProtobufInput.PrematureEofInPackedField.SINT32
|
||||
Required.ProtobufInput.PrematureEofInPackedField.SINT64
|
||||
Required.ProtobufInput.PrematureEofInPackedField.UINT32
|
||||
Required.ProtobufInput.PrematureEofInPackedField.UINT64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32
|
||||
Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput
|
||||
Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput
|
||||
Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput
|
||||
Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput
|
||||
Required.TimestampProtoInputTooLarge.JsonOutput
|
||||
Required.TimestampProtoInputTooSmall.JsonOutput
|
||||
|
@ -42,12 +42,23 @@ declare -a RUNTIME_PROTO_FILES=(\
|
||||
google/protobuf/wrappers.proto)
|
||||
|
||||
declare -a COMPILER_PROTO_FILES=(\
|
||||
google/protobuf/compiler/plugin.proto \
|
||||
google/protobuf/compiler/profile.proto \
|
||||
)
|
||||
google/protobuf/compiler/plugin.proto)
|
||||
|
||||
CORE_PROTO_IS_CORRECT=0
|
||||
PROCESS_ROUND=1
|
||||
BOOTSTRAP_PROTOC=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case $1 in
|
||||
--bootstrap_protoc)
|
||||
BOOTSTRAP_PROTOC=$2
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
TMP=$(mktemp -d)
|
||||
echo "Updating descriptor protos..."
|
||||
while [ $CORE_PROTO_IS_CORRECT -ne 1 ]
|
||||
@ -55,14 +66,20 @@ do
|
||||
echo "Round $PROCESS_ROUND"
|
||||
CORE_PROTO_IS_CORRECT=1
|
||||
|
||||
make $@ protoc
|
||||
if test $? -ne 0; then
|
||||
echo "Failed to build protoc."
|
||||
exit 1
|
||||
if [ "$BOOTSTRAP_PROTOC" != "" ]; then
|
||||
PROTOC=$BOOTSTRAP_PROTOC
|
||||
BOOTSTRAP_PROTOC=""
|
||||
else
|
||||
make $@ protoc
|
||||
if test $? -ne 0; then
|
||||
echo "Failed to build protoc."
|
||||
exit 1
|
||||
fi
|
||||
PROTOC="./protoc"
|
||||
fi
|
||||
|
||||
./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \
|
||||
./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP ${COMPILER_PROTO_FILES[@]}
|
||||
$PROTOC --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \
|
||||
$PROTOC --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP ${COMPILER_PROTO_FILES[@]}
|
||||
|
||||
for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]} ${COMPILER_PROTO_FILES[@]}; do
|
||||
BASE_NAME=${PROTO_FILE%.*}
|
||||
|
@ -5,6 +5,7 @@
|
||||
<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_import.proto"/>
|
||||
<arg value="${protobuf.source.dir}/google/protobuf/unittest_import_public.proto"/>
|
||||
<arg value="${protobuf.source.dir}/google/protobuf/unittest_mset.proto"/>
|
||||
@ -40,4 +41,4 @@
|
||||
<arg value="${test.proto.dir}/com/google/protobuf/map_test.proto"/>
|
||||
<arg value="${test.proto.dir}/com/google/protobuf/map_initialization_order_test.proto"/>
|
||||
</exec>
|
||||
</project>
|
||||
</project>
|
||||
|
@ -32,6 +32,7 @@ package com.google.protobuf;
|
||||
|
||||
import com.google.protobuf.Descriptors.EnumValueDescriptor;
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor;
|
||||
import com.google.protobuf.Descriptors.FileDescriptor.Syntax;
|
||||
import com.google.protobuf.Descriptors.OneofDescriptor;
|
||||
import com.google.protobuf.Internal.EnumLite;
|
||||
import java.io.IOException;
|
||||
@ -162,7 +163,7 @@ public abstract class AbstractMessage
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
||||
private static ByteString toByteString(Object value) {
|
||||
if (value instanceof byte[]) {
|
||||
return ByteString.copyFrom((byte[]) value);
|
||||
@ -170,7 +171,7 @@ public abstract class AbstractMessage
|
||||
return (ByteString) value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares two bytes fields. The parameters must be either a byte array or a
|
||||
* ByteString object. They can be of different type though.
|
||||
@ -181,7 +182,7 @@ public abstract class AbstractMessage
|
||||
}
|
||||
return toByteString(a).equals(toByteString(b));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts a list of MapEntry messages into a Map used for equals() and
|
||||
* hashCode().
|
||||
@ -212,7 +213,7 @@ public abstract class AbstractMessage
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares two map fields. The parameters must be a list of MapEntry
|
||||
* messages.
|
||||
@ -223,13 +224,13 @@ public abstract class AbstractMessage
|
||||
Map mb = convertMapEntryListToMap((List) b);
|
||||
return MapFieldLite.equals(ma, mb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares two set of fields.
|
||||
* This method is used to implement {@link AbstractMessage#equals(Object)}
|
||||
* and {@link AbstractMutableMessage#equals(Object)}. It takes special care
|
||||
* of bytes fields because immutable messages and mutable messages use
|
||||
* different Java type to reprensent a bytes field and this method should be
|
||||
* different Java type to represent a bytes field and this method should be
|
||||
* able to compare immutable messages, mutable messages and also an immutable
|
||||
* message to a mutable message.
|
||||
*/
|
||||
@ -275,7 +276,7 @@ public abstract class AbstractMessage
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the hash code of a map field. {@code value} must be a list of
|
||||
* MapEntry messages.
|
||||
@ -371,7 +372,7 @@ public abstract class AbstractMessage
|
||||
public String getInitializationErrorString() {
|
||||
return MessageReflection.delimitWithCommas(findInitializationErrors());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected BuilderType internalMergeFrom(AbstractMessageLite other) {
|
||||
return mergeFrom((Message) other);
|
||||
@ -432,8 +433,12 @@ public abstract class AbstractMessage
|
||||
final CodedInputStream input,
|
||||
final ExtensionRegistryLite extensionRegistry)
|
||||
throws IOException {
|
||||
boolean discardUnknown =
|
||||
getDescriptorForType().getFile().getSyntax() == Syntax.PROTO3
|
||||
? input.shouldDiscardUnknownFieldsProto3()
|
||||
: input.shouldDiscardUnknownFields();
|
||||
final UnknownFieldSet.Builder unknownFields =
|
||||
UnknownFieldSet.newBuilder(getUnknownFields());
|
||||
discardUnknown ? null : UnknownFieldSet.newBuilder(getUnknownFields());
|
||||
while (true) {
|
||||
final int tag = input.readTag();
|
||||
if (tag == 0) {
|
||||
@ -451,7 +456,9 @@ public abstract class AbstractMessage
|
||||
break;
|
||||
}
|
||||
}
|
||||
setUnknownFields(unknownFields.build());
|
||||
if (unknownFields != null) {
|
||||
setUnknownFields(unknownFields.build());
|
||||
}
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,9 @@ import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A partial implementation of the {@link MessageLite} interface which
|
||||
@ -118,8 +120,13 @@ public abstract class AbstractMessageLite<
|
||||
}
|
||||
}
|
||||
|
||||
protected static <T> void addAll(final Iterable<T> values,
|
||||
final Collection<? super T> list) {
|
||||
// For binary compatibility
|
||||
@Deprecated
|
||||
protected static <T> void addAll(final Iterable<T> values, final Collection<? super T> list) {
|
||||
Builder.addAll(values, (List) list);
|
||||
}
|
||||
|
||||
protected static <T> void addAll(final Iterable<T> values, final List<? super T> list) {
|
||||
Builder.addAll(values, list);
|
||||
}
|
||||
|
||||
@ -334,6 +341,25 @@ public abstract class AbstractMessageLite<
|
||||
+ " threw an IOException (should never happen).";
|
||||
}
|
||||
|
||||
// We check nulls as we iterate to avoid iterating over values twice.
|
||||
private static <T> void addAllCheckingNulls(Iterable<T> values, List<? super T> list) {
|
||||
if (list instanceof ArrayList && values instanceof Collection) {
|
||||
((ArrayList<T>) list).ensureCapacity(list.size() + ((Collection<T>) values).size());
|
||||
}
|
||||
int begin = list.size();
|
||||
for (T value : values) {
|
||||
if (value == null) {
|
||||
// encountered a null value so we must undo our modifications prior to throwing
|
||||
String message = "Element at index " + (list.size() - begin) + " is null.";
|
||||
for (int i = list.size() - 1; i >= begin; i--) {
|
||||
list.remove(i);
|
||||
}
|
||||
throw new NullPointerException(message);
|
||||
}
|
||||
list.add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an UninitializedMessageException reporting missing fields in
|
||||
* the given message.
|
||||
@ -343,16 +369,20 @@ public abstract class AbstractMessageLite<
|
||||
return new UninitializedMessageException(message);
|
||||
}
|
||||
|
||||
// For binary compatibility.
|
||||
@Deprecated
|
||||
protected static <T> void addAll(final Iterable<T> values, final Collection<? super T> list) {
|
||||
addAll(values, (List<T>) list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the {@code values} to the {@code list}. This is a helper method
|
||||
* used by generated code. Users should ignore it.
|
||||
* Adds the {@code values} to the {@code list}. This is a helper method used by generated code.
|
||||
* Users should ignore it.
|
||||
*
|
||||
* @throws NullPointerException if {@code values} or any of the elements of
|
||||
* {@code values} is null. When that happens, some elements of
|
||||
* {@code values} may have already been added to the result {@code list}.
|
||||
* @throws NullPointerException if {@code values} or any of the elements of {@code values} is
|
||||
* null.
|
||||
*/
|
||||
protected static <T> void addAll(final Iterable<T> values,
|
||||
final Collection<? super T> list) {
|
||||
protected static <T> void addAll(final Iterable<T> values, final List<? super T> list) {
|
||||
checkNotNull(values);
|
||||
if (values instanceof LazyStringList) {
|
||||
// For StringOrByteStringLists, check the underlying elements to avoid
|
||||
@ -360,25 +390,31 @@ public abstract class AbstractMessageLite<
|
||||
// TODO(dweis): Could we just prohibit nulls in all protobuf lists and get rid of this? Is
|
||||
// if even possible to hit this condition as all protobuf methods check for null first,
|
||||
// right?
|
||||
checkForNullValues(((LazyStringList) values).getUnderlyingElements());
|
||||
list.addAll((Collection<T>) values);
|
||||
} else if (values instanceof Collection) {
|
||||
if (!(values instanceof PrimitiveNonBoxingCollection)) {
|
||||
checkForNullValues(values);
|
||||
List<?> lazyValues = ((LazyStringList) values).getUnderlyingElements();
|
||||
LazyStringList lazyList = (LazyStringList) list;
|
||||
int begin = list.size();
|
||||
for (Object value : lazyValues) {
|
||||
if (value == null) {
|
||||
// encountered a null value so we must undo our modifications prior to throwing
|
||||
String message = "Element at index " + (lazyList.size() - begin) + " is null.";
|
||||
for (int i = lazyList.size() - 1; i >= begin; i--) {
|
||||
lazyList.remove(i);
|
||||
}
|
||||
throw new NullPointerException(message);
|
||||
}
|
||||
if (value instanceof ByteString) {
|
||||
lazyList.add((ByteString) value);
|
||||
} else {
|
||||
lazyList.add((String) value);
|
||||
}
|
||||
}
|
||||
list.addAll((Collection<T>) values);
|
||||
} else {
|
||||
for (final T value : values) {
|
||||
checkNotNull(value);
|
||||
list.add(value);
|
||||
if (values instanceof PrimitiveNonBoxingCollection) {
|
||||
list.addAll((Collection<T>) values);
|
||||
} else {
|
||||
addAllCheckingNulls(values, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkForNullValues(final Iterable<?> values) {
|
||||
for (final Object value : values) {
|
||||
checkNotNull(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,8 @@ import static com.google.protobuf.Internal.EMPTY_BYTE_ARRAY;
|
||||
import static com.google.protobuf.Internal.EMPTY_BYTE_BUFFER;
|
||||
import static com.google.protobuf.Internal.UTF_8;
|
||||
import static com.google.protobuf.Internal.checkNotNull;
|
||||
import static com.google.protobuf.WireFormat.FIXED_32_SIZE;
|
||||
import static com.google.protobuf.WireFormat.FIXED_64_SIZE;
|
||||
import static com.google.protobuf.WireFormat.FIXED32_SIZE;
|
||||
import static com.google.protobuf.WireFormat.FIXED64_SIZE;
|
||||
import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@ -372,6 +372,64 @@ public abstract class CodedInputStream {
|
||||
return oldLimit;
|
||||
}
|
||||
|
||||
|
||||
private boolean explicitDiscardUnknownFields = false;
|
||||
|
||||
/** TODO(liujisi): flip the default.*/
|
||||
private static volatile boolean proto3DiscardUnknownFieldsDefault = true;
|
||||
|
||||
static void setProto3DiscardUnknownsByDefaultForTest() {
|
||||
proto3DiscardUnknownFieldsDefault = true;
|
||||
}
|
||||
|
||||
static void setProto3KeepUnknownsByDefaultForTest() {
|
||||
proto3DiscardUnknownFieldsDefault = false;
|
||||
}
|
||||
|
||||
static boolean getProto3DiscardUnknownFieldsDefault() {
|
||||
return proto3DiscardUnknownFieldsDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this {@code CodedInputStream} to discard unknown fields. Only applies to full runtime
|
||||
* messages; lite messages will always preserve unknowns.
|
||||
*
|
||||
* <p>Note calling this function alone will have NO immediate effect on the underlying input data.
|
||||
* The unknown fields will be discarded during parsing. This affects both Proto2 and Proto3 full
|
||||
* runtime.
|
||||
*/
|
||||
final void discardUnknownFields() {
|
||||
explicitDiscardUnknownFields = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverts the unknown fields preservation behavior for Proto2 and Proto3 full runtime to their
|
||||
* default.
|
||||
*/
|
||||
final void unsetDiscardUnknownFields() {
|
||||
explicitDiscardUnknownFields = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether unknown fields in this input stream should be discarded during parsing into full
|
||||
* runtime messages.
|
||||
*/
|
||||
final boolean shouldDiscardUnknownFields() {
|
||||
return explicitDiscardUnknownFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether unknown fields in this input stream should be discarded during parsing for proto3 full
|
||||
* runtime messages.
|
||||
*
|
||||
* <p>This function was temporarily introduced before proto3 unknown fields behavior is changed.
|
||||
* TODO(liujisi): remove this and related code in GeneratedMessage after proto3 unknown
|
||||
* fields migration is done.
|
||||
*/
|
||||
final boolean shouldDiscardUnknownFieldsProto3() {
|
||||
return explicitDiscardUnknownFields ? true : proto3DiscardUnknownFieldsDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the current size counter to zero (see {@link #setSizeLimit(int)}). Only valid for {@link
|
||||
* InputStream}-backed streams.
|
||||
@ -572,7 +630,7 @@ public abstract class CodedInputStream {
|
||||
skipRawVarint();
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_FIXED64:
|
||||
skipRawBytes(FIXED_64_SIZE);
|
||||
skipRawBytes(FIXED64_SIZE);
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
|
||||
skipRawBytes(readRawVarint32());
|
||||
@ -585,7 +643,7 @@ public abstract class CodedInputStream {
|
||||
case WireFormat.WIRETYPE_END_GROUP:
|
||||
return false;
|
||||
case WireFormat.WIRETYPE_FIXED32:
|
||||
skipRawBytes(FIXED_32_SIZE);
|
||||
skipRawBytes(FIXED32_SIZE);
|
||||
return true;
|
||||
default:
|
||||
throw InvalidProtocolBufferException.invalidWireType();
|
||||
@ -1064,12 +1122,12 @@ public abstract class CodedInputStream {
|
||||
public int readRawLittleEndian32() throws IOException {
|
||||
int tempPos = pos;
|
||||
|
||||
if (limit - tempPos < FIXED_32_SIZE) {
|
||||
if (limit - tempPos < FIXED32_SIZE) {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
}
|
||||
|
||||
final byte[] buffer = this.buffer;
|
||||
pos = tempPos + FIXED_32_SIZE;
|
||||
pos = tempPos + FIXED32_SIZE;
|
||||
return (((buffer[tempPos] & 0xff))
|
||||
| ((buffer[tempPos + 1] & 0xff) << 8)
|
||||
| ((buffer[tempPos + 2] & 0xff) << 16)
|
||||
@ -1080,12 +1138,12 @@ public abstract class CodedInputStream {
|
||||
public long readRawLittleEndian64() throws IOException {
|
||||
int tempPos = pos;
|
||||
|
||||
if (limit - tempPos < FIXED_64_SIZE) {
|
||||
if (limit - tempPos < FIXED64_SIZE) {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
}
|
||||
|
||||
final byte[] buffer = this.buffer;
|
||||
pos = tempPos + FIXED_64_SIZE;
|
||||
pos = tempPos + FIXED64_SIZE;
|
||||
return (((buffer[tempPos] & 0xffL))
|
||||
| ((buffer[tempPos + 1] & 0xffL) << 8)
|
||||
| ((buffer[tempPos + 2] & 0xffL) << 16)
|
||||
@ -1290,7 +1348,7 @@ public abstract class CodedInputStream {
|
||||
skipRawVarint();
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_FIXED64:
|
||||
skipRawBytes(FIXED_64_SIZE);
|
||||
skipRawBytes(FIXED64_SIZE);
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
|
||||
skipRawBytes(readRawVarint32());
|
||||
@ -1303,7 +1361,7 @@ public abstract class CodedInputStream {
|
||||
case WireFormat.WIRETYPE_END_GROUP:
|
||||
return false;
|
||||
case WireFormat.WIRETYPE_FIXED32:
|
||||
skipRawBytes(FIXED_32_SIZE);
|
||||
skipRawBytes(FIXED32_SIZE);
|
||||
return true;
|
||||
default:
|
||||
throw InvalidProtocolBufferException.invalidWireType();
|
||||
@ -1429,7 +1487,9 @@ public abstract class CodedInputStream {
|
||||
final int size = readRawVarint32();
|
||||
if (size > 0 && size <= remaining()) {
|
||||
// TODO(nathanmittler): Is there a way to avoid this copy?
|
||||
byte[] bytes = copyToArray(pos, pos + size);
|
||||
// The same as readBytes' logic
|
||||
byte[] bytes = new byte[size];
|
||||
UnsafeUtil.copyMemory(pos, bytes, 0, size);
|
||||
String result = new String(bytes, UTF_8);
|
||||
pos += size;
|
||||
return result;
|
||||
@ -1449,7 +1509,9 @@ public abstract class CodedInputStream {
|
||||
final int size = readRawVarint32();
|
||||
if (size >= 0 && size <= remaining()) {
|
||||
// TODO(nathanmittler): Is there a way to avoid this copy?
|
||||
byte[] bytes = copyToArray(pos, pos + size);
|
||||
// The same as readBytes' logic
|
||||
byte[] bytes = new byte[size];
|
||||
UnsafeUtil.copyMemory(pos, bytes, 0, size);
|
||||
// TODO(martinrb): We could save a pass by validating while decoding.
|
||||
if (!Utf8.isValidUtf8(bytes)) {
|
||||
throw InvalidProtocolBufferException.invalidUtf8();
|
||||
@ -1545,14 +1607,17 @@ public abstract class CodedInputStream {
|
||||
public ByteString readBytes() throws IOException {
|
||||
final int size = readRawVarint32();
|
||||
if (size > 0 && size <= remaining()) {
|
||||
ByteBuffer result;
|
||||
if (immutable && enableAliasing) {
|
||||
result = slice(pos, pos + size);
|
||||
final ByteBuffer result = slice(pos, pos + size);
|
||||
pos += size;
|
||||
return ByteString.wrap(result);
|
||||
} else {
|
||||
result = copy(pos, pos + size);
|
||||
// Use UnsafeUtil to copy the memory to bytes instead of using ByteBuffer ways.
|
||||
byte[] bytes = new byte[size];
|
||||
UnsafeUtil.copyMemory(pos, bytes, 0, size);
|
||||
pos += size;
|
||||
return ByteString.wrap(bytes);
|
||||
}
|
||||
pos += size;
|
||||
return ByteString.wrap(result);
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
@ -1573,18 +1638,21 @@ public abstract class CodedInputStream {
|
||||
public ByteBuffer readByteBuffer() throws IOException {
|
||||
final int size = readRawVarint32();
|
||||
if (size > 0 && size <= remaining()) {
|
||||
ByteBuffer result;
|
||||
// "Immutable" implies that buffer is backing a ByteString.
|
||||
// Disallow slicing in this case to prevent the caller from modifying the contents
|
||||
// of the ByteString.
|
||||
if (!immutable && enableAliasing) {
|
||||
result = slice(pos, pos + size);
|
||||
final ByteBuffer result = slice(pos, pos + size);
|
||||
pos += size;
|
||||
return result;
|
||||
} else {
|
||||
result = copy(pos, pos + size);
|
||||
// The same as readBytes' logic
|
||||
byte[] bytes = new byte[size];
|
||||
UnsafeUtil.copyMemory(pos, bytes, 0, size);
|
||||
pos += size;
|
||||
return ByteBuffer.wrap(bytes);
|
||||
}
|
||||
pos += size;
|
||||
// TODO(nathanmittler): Investigate making the ByteBuffer be made read-only
|
||||
return result;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
@ -1785,11 +1853,11 @@ public abstract class CodedInputStream {
|
||||
public int readRawLittleEndian32() throws IOException {
|
||||
long tempPos = pos;
|
||||
|
||||
if (limit - tempPos < FIXED_32_SIZE) {
|
||||
if (limit - tempPos < FIXED32_SIZE) {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
}
|
||||
|
||||
pos = tempPos + FIXED_32_SIZE;
|
||||
pos = tempPos + FIXED32_SIZE;
|
||||
return (((UnsafeUtil.getByte(tempPos) & 0xff))
|
||||
| ((UnsafeUtil.getByte(tempPos + 1) & 0xff) << 8)
|
||||
| ((UnsafeUtil.getByte(tempPos + 2) & 0xff) << 16)
|
||||
@ -1800,11 +1868,11 @@ public abstract class CodedInputStream {
|
||||
public long readRawLittleEndian64() throws IOException {
|
||||
long tempPos = pos;
|
||||
|
||||
if (limit - tempPos < FIXED_64_SIZE) {
|
||||
if (limit - tempPos < FIXED64_SIZE) {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
}
|
||||
|
||||
pos = tempPos + FIXED_64_SIZE;
|
||||
pos = tempPos + FIXED64_SIZE;
|
||||
return (((UnsafeUtil.getByte(tempPos) & 0xffL))
|
||||
| ((UnsafeUtil.getByte(tempPos + 1) & 0xffL) << 8)
|
||||
| ((UnsafeUtil.getByte(tempPos + 2) & 0xffL) << 16)
|
||||
@ -1943,27 +2011,6 @@ public abstract class CodedInputStream {
|
||||
buffer.limit(prevLimit);
|
||||
}
|
||||
}
|
||||
|
||||
private ByteBuffer copy(long begin, long end) throws IOException {
|
||||
return ByteBuffer.wrap(copyToArray(begin, end));
|
||||
}
|
||||
|
||||
private byte[] copyToArray(long begin, long end) throws IOException {
|
||||
int prevPos = buffer.position();
|
||||
int prevLimit = buffer.limit();
|
||||
try {
|
||||
buffer.position(bufferPos(begin));
|
||||
buffer.limit(bufferPos(end));
|
||||
byte[] bytes = new byte[(int) (end - begin)];
|
||||
buffer.get(bytes);
|
||||
return bytes;
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
} finally {
|
||||
buffer.position(prevPos);
|
||||
buffer.limit(prevLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2034,7 +2081,7 @@ public abstract class CodedInputStream {
|
||||
skipRawVarint();
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_FIXED64:
|
||||
skipRawBytes(FIXED_64_SIZE);
|
||||
skipRawBytes(FIXED64_SIZE);
|
||||
return true;
|
||||
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
|
||||
skipRawBytes(readRawVarint32());
|
||||
@ -2047,7 +2094,7 @@ public abstract class CodedInputStream {
|
||||
case WireFormat.WIRETYPE_END_GROUP:
|
||||
return false;
|
||||
case WireFormat.WIRETYPE_FIXED32:
|
||||
skipRawBytes(FIXED_32_SIZE);
|
||||
skipRawBytes(FIXED32_SIZE);
|
||||
return true;
|
||||
default:
|
||||
throw InvalidProtocolBufferException.invalidWireType();
|
||||
@ -2332,8 +2379,7 @@ public abstract class CodedInputStream {
|
||||
if (size == 0) {
|
||||
return ByteString.EMPTY;
|
||||
}
|
||||
// Slow path: Build a byte array first then copy it.
|
||||
return ByteString.wrap(readRawBytesSlowPath(size));
|
||||
return readBytesSlowPath(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2558,13 +2604,13 @@ public abstract class CodedInputStream {
|
||||
public int readRawLittleEndian32() throws IOException {
|
||||
int tempPos = pos;
|
||||
|
||||
if (bufferSize - tempPos < FIXED_32_SIZE) {
|
||||
refillBuffer(FIXED_32_SIZE);
|
||||
if (bufferSize - tempPos < FIXED32_SIZE) {
|
||||
refillBuffer(FIXED32_SIZE);
|
||||
tempPos = pos;
|
||||
}
|
||||
|
||||
final byte[] buffer = this.buffer;
|
||||
pos = tempPos + FIXED_32_SIZE;
|
||||
pos = tempPos + FIXED32_SIZE;
|
||||
return (((buffer[tempPos] & 0xff))
|
||||
| ((buffer[tempPos + 1] & 0xff) << 8)
|
||||
| ((buffer[tempPos + 2] & 0xff) << 16)
|
||||
@ -2575,13 +2621,13 @@ public abstract class CodedInputStream {
|
||||
public long readRawLittleEndian64() throws IOException {
|
||||
int tempPos = pos;
|
||||
|
||||
if (bufferSize - tempPos < FIXED_64_SIZE) {
|
||||
refillBuffer(FIXED_64_SIZE);
|
||||
if (bufferSize - tempPos < FIXED64_SIZE) {
|
||||
refillBuffer(FIXED64_SIZE);
|
||||
tempPos = pos;
|
||||
}
|
||||
|
||||
final byte[] buffer = this.buffer;
|
||||
pos = tempPos + FIXED_64_SIZE;
|
||||
pos = tempPos + FIXED64_SIZE;
|
||||
return (((buffer[tempPos] & 0xffL))
|
||||
| ((buffer[tempPos + 1] & 0xffL) << 8)
|
||||
| ((buffer[tempPos + 2] & 0xffL) << 16)
|
||||
@ -2675,7 +2721,13 @@ public abstract class CodedInputStream {
|
||||
*/
|
||||
private void refillBuffer(int n) throws IOException {
|
||||
if (!tryRefillBuffer(n)) {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
// We have to distinguish the exception between sizeLimitExceeded and truncatedMessage. So
|
||||
// we just throw an sizeLimitExceeded exception here if it exceeds the sizeLimit
|
||||
if (n > sizeLimit - totalBytesRetired - pos) {
|
||||
throw InvalidProtocolBufferException.sizeLimitExceeded();
|
||||
} else {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2684,8 +2736,8 @@ public abstract class CodedInputStream {
|
||||
* buffer. Caller must ensure that the requested space is not yet available, and that the
|
||||
* requested space is less than BUFFER_SIZE.
|
||||
*
|
||||
* @return {@code true} if the bytes could be made available; {@code false} if the end of the
|
||||
* stream or the current limit was reached.
|
||||
* @return {@code true} If the bytes could be made available; {@code false} 1. Current at the
|
||||
* end of the stream 2. The current limit was reached 3. The total size limit was reached
|
||||
*/
|
||||
private boolean tryRefillBuffer(int n) throws IOException {
|
||||
if (pos + n <= bufferSize) {
|
||||
@ -2693,6 +2745,14 @@ public abstract class CodedInputStream {
|
||||
"refillBuffer() called when " + n + " bytes were already available in buffer");
|
||||
}
|
||||
|
||||
// Check whether the size of total message needs to read is bigger than the size limit.
|
||||
// We shouldn't throw an exception here as isAtEnd() function needs to get this function's
|
||||
// return as the result.
|
||||
if (n > sizeLimit - totalBytesRetired - pos) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Shouldn't throw the exception here either.
|
||||
if (totalBytesRetired + pos + n > currentLimit) {
|
||||
// Oops, we hit a limit.
|
||||
return false;
|
||||
@ -2712,7 +2772,16 @@ public abstract class CodedInputStream {
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
int bytesRead = input.read(buffer, bufferSize, buffer.length - bufferSize);
|
||||
// Here we should refill the buffer as many bytes as possible.
|
||||
int bytesRead =
|
||||
input.read(
|
||||
buffer,
|
||||
bufferSize,
|
||||
Math.min(
|
||||
// the size of allocated but unused bytes in the buffer
|
||||
buffer.length - bufferSize,
|
||||
// do not exceed the total bytes limit
|
||||
sizeLimit - totalBytesRetired - bufferSize));
|
||||
if (bytesRead == 0 || bytesRead < -1 || bytesRead > buffer.length) {
|
||||
throw new IllegalStateException(
|
||||
"InputStream#read(byte[]) returned invalid result: "
|
||||
@ -2721,10 +2790,6 @@ public abstract class CodedInputStream {
|
||||
}
|
||||
if (bytesRead > 0) {
|
||||
bufferSize += bytesRead;
|
||||
// Integer-overflow-conscious check against sizeLimit
|
||||
if (totalBytesRetired + n - sizeLimit > 0) {
|
||||
throw InvalidProtocolBufferException.sizeLimitExceeded();
|
||||
}
|
||||
recomputeBufferSizeAfterLimit();
|
||||
return (bufferSize >= n) ? true : tryRefillBuffer(n);
|
||||
}
|
||||
@ -2756,6 +2821,49 @@ public abstract class CodedInputStream {
|
||||
* (bufferSize - pos) && size > 0)
|
||||
*/
|
||||
private byte[] readRawBytesSlowPath(final int size) 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;
|
||||
}
|
||||
|
||||
final int originalBufferPos = pos;
|
||||
final int bufferedBytes = bufferSize - pos;
|
||||
|
||||
// Mark the current buffer consumed.
|
||||
totalBytesRetired += bufferSize;
|
||||
pos = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
// Determine the number of bytes we need to read from the input stream.
|
||||
int sizeLeft = size - bufferedBytes;
|
||||
|
||||
// The size is very large. For security reasons we read them in small
|
||||
// chunks.
|
||||
List<byte[]> chunks = readRawBytesSlowPathRemainingChunks(sizeLeft);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Done.
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private byte[] readRawBytesSlowPathOneChunk(final int size) throws IOException {
|
||||
if (size == 0) {
|
||||
return Internal.EMPTY_BYTE_ARRAY;
|
||||
}
|
||||
@ -2776,14 +2884,7 @@ public abstract class CodedInputStream {
|
||||
throw InvalidProtocolBufferException.truncatedMessage();
|
||||
}
|
||||
|
||||
final int originalBufferPos = pos;
|
||||
final int bufferedBytes = bufferSize - pos;
|
||||
|
||||
// Mark the current buffer consumed.
|
||||
totalBytesRetired += bufferSize;
|
||||
pos = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
// Determine the number of bytes we need to read from the input stream.
|
||||
int sizeLeft = size - bufferedBytes;
|
||||
// TODO(nathanmittler): Consider using a value larger than DEFAULT_BUFFER_SIZE.
|
||||
@ -2793,7 +2894,10 @@ public abstract class CodedInputStream {
|
||||
final byte[] bytes = new byte[size];
|
||||
|
||||
// Copy all of the buffered bytes to the result buffer.
|
||||
System.arraycopy(buffer, originalBufferPos, bytes, 0, bufferedBytes);
|
||||
System.arraycopy(buffer, pos, bytes, 0, bufferedBytes);
|
||||
totalBytesRetired += bufferSize;
|
||||
pos = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
// Fill the remaining bytes from the input stream.
|
||||
int tempPos = bufferedBytes;
|
||||
@ -2809,6 +2913,11 @@ public abstract class CodedInputStream {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Reads the remaining data in small chunks from the input stream. */
|
||||
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
|
||||
// maliciously-crafted message could provide a bogus very large size in
|
||||
@ -2834,21 +2943,41 @@ public abstract class CodedInputStream {
|
||||
chunks.add(chunk);
|
||||
}
|
||||
|
||||
// OK, got everything. Now concatenate it all into one buffer.
|
||||
final byte[] bytes = new byte[size];
|
||||
return chunks;
|
||||
}
|
||||
|
||||
// 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;
|
||||
/**
|
||||
* Like readBytes, but caller must have already checked the fast path: (size <= (bufferSize -
|
||||
* pos) && size > 0 || size == 0)
|
||||
*/
|
||||
private ByteString readBytesSlowPath(final int size) throws IOException {
|
||||
final byte[] result = readRawBytesSlowPathOneChunk(size);
|
||||
if (result != null) {
|
||||
return ByteString.wrap(result);
|
||||
}
|
||||
|
||||
// Done.
|
||||
return bytes;
|
||||
final int originalBufferPos = pos;
|
||||
final int bufferedBytes = bufferSize - pos;
|
||||
|
||||
// Mark the current buffer consumed.
|
||||
totalBytesRetired += bufferSize;
|
||||
pos = 0;
|
||||
bufferSize = 0;
|
||||
|
||||
// Determine the number of bytes we need to read from the input stream.
|
||||
int sizeLeft = size - bufferedBytes;
|
||||
|
||||
// The size is very large. For security reasons we read them in small
|
||||
// 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));
|
||||
}
|
||||
return ByteString.copyFrom(byteStrings);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -30,8 +30,8 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import static com.google.protobuf.WireFormat.FIXED_32_SIZE;
|
||||
import static com.google.protobuf.WireFormat.FIXED_64_SIZE;
|
||||
import static com.google.protobuf.WireFormat.FIXED32_SIZE;
|
||||
import static com.google.protobuf.WireFormat.FIXED64_SIZE;
|
||||
import static com.google.protobuf.WireFormat.MAX_VARINT_SIZE;
|
||||
import static java.lang.Math.max;
|
||||
|
||||
@ -59,13 +59,12 @@ import java.util.logging.Logger;
|
||||
public abstract class CodedOutputStream extends ByteOutput {
|
||||
private static final Logger logger = Logger.getLogger(CodedOutputStream.class.getName());
|
||||
private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = UnsafeUtil.hasUnsafeArrayOperations();
|
||||
private static final long ARRAY_BASE_OFFSET = UnsafeUtil.getArrayBaseOffset();
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #computeFixed32SizeNoTag(int)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public static final int LITTLE_ENDIAN_32_SIZE = FIXED_32_SIZE;
|
||||
public static final int LITTLE_ENDIAN_32_SIZE = FIXED32_SIZE;
|
||||
|
||||
/**
|
||||
* The buffer size used in {@link #newInstance(OutputStream)}.
|
||||
@ -755,7 +754,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
* {@code fixed32} field.
|
||||
*/
|
||||
public static int computeFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) {
|
||||
return FIXED_32_SIZE;
|
||||
return FIXED32_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -763,7 +762,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
* {@code sfixed32} field.
|
||||
*/
|
||||
public static int computeSFixed32SizeNoTag(@SuppressWarnings("unused") final int unused) {
|
||||
return FIXED_32_SIZE;
|
||||
return FIXED32_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -813,7 +812,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
* {@code fixed64} field.
|
||||
*/
|
||||
public static int computeFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) {
|
||||
return FIXED_64_SIZE;
|
||||
return FIXED64_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -821,7 +820,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
* {@code sfixed64} field.
|
||||
*/
|
||||
public static int computeSFixed64SizeNoTag(@SuppressWarnings("unused") final long unused) {
|
||||
return FIXED_64_SIZE;
|
||||
return FIXED64_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -829,7 +828,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
* {@code float} field, including tag.
|
||||
*/
|
||||
public static int computeFloatSizeNoTag(@SuppressWarnings("unused") final float unused) {
|
||||
return FIXED_32_SIZE;
|
||||
return FIXED32_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -837,7 +836,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
* {@code double} field, including tag.
|
||||
*/
|
||||
public static int computeDoubleSizeNoTag(@SuppressWarnings("unused") final double unused) {
|
||||
return FIXED_64_SIZE;
|
||||
return FIXED64_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1321,15 +1320,12 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
@Override
|
||||
public final void writeUInt32NoTag(int value) throws IOException {
|
||||
if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
|
||||
long pos = ARRAY_BASE_OFFSET + position;
|
||||
while (true) {
|
||||
if ((value & ~0x7F) == 0) {
|
||||
UnsafeUtil.putByte(buffer, pos++, (byte) value);
|
||||
position++;
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) value);
|
||||
return;
|
||||
} else {
|
||||
UnsafeUtil.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80));
|
||||
position++;
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) ((value & 0x7F) | 0x80));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
@ -1367,15 +1363,12 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
@Override
|
||||
public final void writeUInt64NoTag(long value) throws IOException {
|
||||
if (HAS_UNSAFE_ARRAY_OPERATIONS && spaceLeft() >= MAX_VARINT_SIZE) {
|
||||
long pos = ARRAY_BASE_OFFSET + position;
|
||||
while (true) {
|
||||
if ((value & ~0x7FL) == 0) {
|
||||
UnsafeUtil.putByte(buffer, pos++, (byte) value);
|
||||
position++;
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) value);
|
||||
return;
|
||||
} else {
|
||||
UnsafeUtil.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80));
|
||||
position++;
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) (((int) value & 0x7F) | 0x80));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
@ -1854,7 +1847,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
}
|
||||
|
||||
static boolean isSupported() {
|
||||
return UnsafeUtil.hasUnsafeByteBufferOperations() && UnsafeUtil.hasUnsafeCopyMemory();
|
||||
return UnsafeUtil.hasUnsafeByteBufferOperations();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2030,7 +2023,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
@Override
|
||||
public void writeFixed32NoTag(int value) throws IOException {
|
||||
buffer.putInt(bufferPos(position), value);
|
||||
position += FIXED_32_SIZE;
|
||||
position += FIXED32_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2064,7 +2057,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
@Override
|
||||
public void writeFixed64NoTag(long value) throws IOException {
|
||||
buffer.putLong(bufferPos(position), value);
|
||||
position += FIXED_64_SIZE;
|
||||
position += FIXED64_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -2081,8 +2074,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
String.format("Pos: %d, limit: %d, len: %d", position, limit, length));
|
||||
}
|
||||
|
||||
UnsafeUtil.copyMemory(
|
||||
value, UnsafeUtil.getArrayBaseOffset() + offset, null, position, length);
|
||||
UnsafeUtil.copyMemory(value, offset, position, length);
|
||||
position += length;
|
||||
}
|
||||
|
||||
@ -2249,19 +2241,17 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
*/
|
||||
final void bufferUInt32NoTag(int value) {
|
||||
if (HAS_UNSAFE_ARRAY_OPERATIONS) {
|
||||
final long originalPos = ARRAY_BASE_OFFSET + position;
|
||||
long pos = originalPos;
|
||||
final long originalPos = position;
|
||||
while (true) {
|
||||
if ((value & ~0x7F) == 0) {
|
||||
UnsafeUtil.putByte(buffer, pos++, (byte) value);
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) value);
|
||||
break;
|
||||
} else {
|
||||
UnsafeUtil.putByte(buffer, pos++, (byte) ((value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) ((value & 0x7F) | 0x80));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
int delta = (int) (pos - originalPos);
|
||||
position += delta;
|
||||
int delta = (int) (position - originalPos);
|
||||
totalBytesWritten += delta;
|
||||
} else {
|
||||
while (true) {
|
||||
@ -2284,19 +2274,17 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
*/
|
||||
final void bufferUInt64NoTag(long value) {
|
||||
if (HAS_UNSAFE_ARRAY_OPERATIONS) {
|
||||
final long originalPos = ARRAY_BASE_OFFSET + position;
|
||||
long pos = originalPos;
|
||||
final long originalPos = position;
|
||||
while (true) {
|
||||
if ((value & ~0x7FL) == 0) {
|
||||
UnsafeUtil.putByte(buffer, pos++, (byte) value);
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) value);
|
||||
break;
|
||||
} else {
|
||||
UnsafeUtil.putByte(buffer, pos++, (byte) (((int) value & 0x7F) | 0x80));
|
||||
UnsafeUtil.putByte(buffer, position++, (byte) (((int) value & 0x7F) | 0x80));
|
||||
value >>>= 7;
|
||||
}
|
||||
}
|
||||
int delta = (int) (pos - originalPos);
|
||||
position += delta;
|
||||
int delta = (int) (position - originalPos);
|
||||
totalBytesWritten += delta;
|
||||
} else {
|
||||
while (true) {
|
||||
@ -2322,7 +2310,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
buffer[position++] = (byte) ((value >> 8) & 0xFF);
|
||||
buffer[position++] = (byte) ((value >> 16) & 0xFF);
|
||||
buffer[position++] = (byte) ((value >> 24) & 0xFF);
|
||||
totalBytesWritten += FIXED_32_SIZE;
|
||||
totalBytesWritten += FIXED32_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2338,7 +2326,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
buffer[position++] = (byte) ((int) (value >> 40) & 0xFF);
|
||||
buffer[position++] = (byte) ((int) (value >> 48) & 0xFF);
|
||||
buffer[position++] = (byte) ((int) (value >> 56) & 0xFF);
|
||||
totalBytesWritten += FIXED_64_SIZE;
|
||||
totalBytesWritten += FIXED64_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2379,7 +2367,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
|
||||
@Override
|
||||
public void writeFixed32(final int fieldNumber, final int value) throws IOException {
|
||||
flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_32_SIZE);
|
||||
flushIfNotAvailable(MAX_VARINT_SIZE + FIXED32_SIZE);
|
||||
bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
|
||||
bufferFixed32NoTag(value);
|
||||
}
|
||||
@ -2393,7 +2381,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
|
||||
@Override
|
||||
public void writeFixed64(final int fieldNumber, final long value) throws IOException {
|
||||
flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_64_SIZE);
|
||||
flushIfNotAvailable(MAX_VARINT_SIZE + FIXED64_SIZE);
|
||||
bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
|
||||
bufferFixed64NoTag(value);
|
||||
}
|
||||
@ -2519,7 +2507,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
|
||||
@Override
|
||||
public void writeFixed32NoTag(final int value) throws IOException {
|
||||
flushIfNotAvailable(FIXED_32_SIZE);
|
||||
flushIfNotAvailable(FIXED32_SIZE);
|
||||
bufferFixed32NoTag(value);
|
||||
}
|
||||
|
||||
@ -2531,7 +2519,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
|
||||
@Override
|
||||
public void writeFixed64NoTag(final long value) throws IOException {
|
||||
flushIfNotAvailable(FIXED_64_SIZE);
|
||||
flushIfNotAvailable(FIXED64_SIZE);
|
||||
bufferFixed64NoTag(value);
|
||||
}
|
||||
|
||||
@ -2682,7 +2670,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
|
||||
@Override
|
||||
public void writeFixed32(final int fieldNumber, final int value) throws IOException {
|
||||
flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_32_SIZE);
|
||||
flushIfNotAvailable(MAX_VARINT_SIZE + FIXED32_SIZE);
|
||||
bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED32);
|
||||
bufferFixed32NoTag(value);
|
||||
}
|
||||
@ -2696,7 +2684,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
|
||||
@Override
|
||||
public void writeFixed64(final int fieldNumber, final long value) throws IOException {
|
||||
flushIfNotAvailable(MAX_VARINT_SIZE + FIXED_64_SIZE);
|
||||
flushIfNotAvailable(MAX_VARINT_SIZE + FIXED64_SIZE);
|
||||
bufferTag(fieldNumber, WireFormat.WIRETYPE_FIXED64);
|
||||
bufferFixed64NoTag(value);
|
||||
}
|
||||
@ -2822,7 +2810,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
|
||||
@Override
|
||||
public void writeFixed32NoTag(final int value) throws IOException {
|
||||
flushIfNotAvailable(FIXED_32_SIZE);
|
||||
flushIfNotAvailable(FIXED32_SIZE);
|
||||
bufferFixed32NoTag(value);
|
||||
}
|
||||
|
||||
@ -2834,7 +2822,7 @@ public abstract class CodedOutputStream extends ByteOutput {
|
||||
|
||||
@Override
|
||||
public void writeFixed64NoTag(final long value) throws IOException {
|
||||
flushIfNotAvailable(FIXED_64_SIZE);
|
||||
flushIfNotAvailable(FIXED64_SIZE);
|
||||
bufferFixed64NoTag(value);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (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;
|
||||
|
||||
/**
|
||||
* Parsers to discard unknown fields during parsing.
|
||||
*/
|
||||
public final class DiscardUnknownFieldsParser {
|
||||
|
||||
/**
|
||||
* Warps a given {@link Parser} into a new {@link Parser} that discards unknown fields during
|
||||
* parsing.
|
||||
*
|
||||
* <p>Usage example:
|
||||
* <pre>{@code
|
||||
* private final static Parser<Foo> FOO_PARSER = DiscardUnknownFieldsParser.wrap(Foo.parser());
|
||||
* Foo parseFooDiscardUnknown(ByteBuffer input) throws IOException {
|
||||
* return FOO_PARSER.parseFrom(input);
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <p>Like all other implementations of {@code Parser}, this parser is stateless and thread-safe.
|
||||
*
|
||||
* @param parser The delegated parser that parses messages.
|
||||
* @return a {@link Parser} that will discard unknown fields during parsing.
|
||||
*/
|
||||
public static final <T extends Message> Parser<T> wrap(final Parser<T> parser) {
|
||||
return new AbstractParser<T>() {
|
||||
@Override
|
||||
public T parsePartialFrom(CodedInputStream input, ExtensionRegistryLite extensionRegistry)
|
||||
throws InvalidProtocolBufferException {
|
||||
try {
|
||||
input.discardUnknownFields();
|
||||
return parser.parsePartialFrom(input, extensionRegistry);
|
||||
} finally {
|
||||
input.unsetDiscardUnknownFields();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private DiscardUnknownFieldsParser() {}
|
||||
}
|
@ -590,9 +590,8 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
|
||||
@Override
|
||||
public Builder setUnknownFields(UnknownFieldSet unknownFields) {
|
||||
if (getDescriptorForType().getFile().getSyntax()
|
||||
== Descriptors.FileDescriptor.Syntax.PROTO3) {
|
||||
// Proto3 discards unknown fields.
|
||||
if (getDescriptorForType().getFile().getSyntax() == Descriptors.FileDescriptor.Syntax.PROTO3
|
||||
&& CodedInputStream.getProto3DiscardUnknownFieldsDefault()) {
|
||||
return this;
|
||||
}
|
||||
this.unknownFields = unknownFields;
|
||||
@ -601,9 +600,8 @@ public final class DynamicMessage extends AbstractMessage {
|
||||
|
||||
@Override
|
||||
public Builder mergeUnknownFields(UnknownFieldSet unknownFields) {
|
||||
if (getDescriptorForType().getFile().getSyntax()
|
||||
== Descriptors.FileDescriptor.Syntax.PROTO3) {
|
||||
// Proto3 discards unknown fields.
|
||||
if (getDescriptorForType().getFile().getSyntax() == Descriptors.FileDescriptor.Syntax.PROTO3
|
||||
&& CodedInputStream.getProto3DiscardUnknownFieldsDefault()) {
|
||||
return this;
|
||||
}
|
||||
this.unknownFields =
|
||||
|
@ -58,10 +58,7 @@ public abstract class Extension<ContainingType extends MessageLite, Type>
|
||||
PROTO1,
|
||||
}
|
||||
|
||||
protected ExtensionType getExtensionType() {
|
||||
// TODO(liujisi): make this abstract after we fix proto1.
|
||||
return ExtensionType.IMMUTABLE;
|
||||
}
|
||||
protected abstract ExtensionType getExtensionType();
|
||||
|
||||
/**
|
||||
* Type of a message extension.
|
||||
@ -70,7 +67,7 @@ public abstract class Extension<ContainingType extends MessageLite, Type>
|
||||
PROTO1,
|
||||
PROTO2,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the extension is a message extension (i.e., getLiteType() == MESSAGE),
|
||||
* returns the type of the message, otherwise undefined.
|
||||
|
@ -34,7 +34,7 @@ import static com.google.protobuf.ExtensionRegistryLite.EMPTY_REGISTRY_LITE;
|
||||
|
||||
/**
|
||||
* A factory object to create instances of {@link ExtensionRegistryLite}.
|
||||
*
|
||||
*
|
||||
* <p>
|
||||
* This factory detects (via reflection) if the full (non-Lite) protocol buffer libraries
|
||||
* are available, and if so, the instances returned are actually {@link ExtensionRegistry}.
|
||||
@ -82,6 +82,7 @@ final class ExtensionRegistryFactory {
|
||||
return EMPTY_REGISTRY_LITE;
|
||||
}
|
||||
|
||||
|
||||
static boolean isFullRegistry(ExtensionRegistryLite registry) {
|
||||
return EXTENSION_REGISTRY_CLASS != null
|
||||
&& EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass());
|
||||
@ -90,6 +91,6 @@ final class ExtensionRegistryFactory {
|
||||
private static final ExtensionRegistryLite invokeSubclassFactory(String methodName)
|
||||
throws Exception {
|
||||
return (ExtensionRegistryLite) EXTENSION_REGISTRY_CLASS
|
||||
.getMethod(methodName).invoke(null);
|
||||
.getDeclaredMethod(methodName).invoke(null);
|
||||
}
|
||||
}
|
||||
|
@ -107,11 +107,12 @@ public abstract class GeneratedMessageLite<
|
||||
@SuppressWarnings("unchecked") // Guaranteed by runtime
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (memoizedHashCode == 0) {
|
||||
HashCodeVisitor visitor = new HashCodeVisitor();
|
||||
visit(visitor, (MessageType) this);
|
||||
memoizedHashCode = visitor.hashCode;
|
||||
if (memoizedHashCode != 0) {
|
||||
return memoizedHashCode;
|
||||
}
|
||||
HashCodeVisitor visitor = new HashCodeVisitor();
|
||||
visit(visitor, (MessageType) this);
|
||||
memoizedHashCode = visitor.hashCode;
|
||||
return memoizedHashCode;
|
||||
}
|
||||
|
||||
@ -331,7 +332,7 @@ public abstract class GeneratedMessageLite<
|
||||
if (isBuilt) {
|
||||
MessageType newInstance =
|
||||
(MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
|
||||
newInstance.visit(MergeFromVisitor.INSTANCE, instance);
|
||||
mergeFromInstance(newInstance, instance);
|
||||
instance = newInstance;
|
||||
isBuilt = false;
|
||||
}
|
||||
@ -386,10 +387,14 @@ public abstract class GeneratedMessageLite<
|
||||
/** All subclasses implement this. */
|
||||
public BuilderType mergeFrom(MessageType message) {
|
||||
copyOnWrite();
|
||||
instance.visit(MergeFromVisitor.INSTANCE, message);
|
||||
mergeFromInstance(instance, message);
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
private void mergeFromInstance(MessageType dest, MessageType src) {
|
||||
dest.visit(MergeFromVisitor.INSTANCE, src);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageType getDefaultInstanceForType() {
|
||||
return defaultInstance;
|
||||
@ -1713,7 +1718,6 @@ public abstract class GeneratedMessageLite<
|
||||
Object visitOneofLong(boolean minePresent, Object mine, Object other);
|
||||
Object visitOneofString(boolean minePresent, Object mine, Object other);
|
||||
Object visitOneofByteString(boolean minePresent, Object mine, Object other);
|
||||
Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other);
|
||||
Object visitOneofMessage(boolean minePresent, Object mine, Object other);
|
||||
void visitOneofNotSet(boolean minePresent);
|
||||
|
||||
@ -1721,7 +1725,6 @@ public abstract class GeneratedMessageLite<
|
||||
* Message fields use null sentinals.
|
||||
*/
|
||||
<T extends MessageLite> T visitMessage(T mine, T other);
|
||||
LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other);
|
||||
|
||||
<T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other);
|
||||
BooleanList visitBooleanList(BooleanList mine, BooleanList other);
|
||||
@ -1864,14 +1867,6 @@ public abstract class GeneratedMessageLite<
|
||||
throw NOT_EQUALS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
|
||||
if (minePresent && mine.equals(other)) {
|
||||
return mine;
|
||||
}
|
||||
throw NOT_EQUALS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
|
||||
if (minePresent && ((GeneratedMessageLite<?, ?>) mine).equals(this, (MessageLite) other)) {
|
||||
@ -1902,21 +1897,6 @@ public abstract class GeneratedMessageLite<
|
||||
return mine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyFieldLite visitLazyMessage(
|
||||
LazyFieldLite mine, LazyFieldLite other) {
|
||||
if (mine == null && other == null) {
|
||||
return null;
|
||||
}
|
||||
if (mine == null || other == null) {
|
||||
throw NOT_EQUALS;
|
||||
}
|
||||
if (mine.equals(other)) {
|
||||
return mine;
|
||||
}
|
||||
throw NOT_EQUALS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
|
||||
if (!mine.equals(other)) {
|
||||
@ -2093,12 +2073,6 @@ public abstract class GeneratedMessageLite<
|
||||
return mine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
|
||||
hashCode = (53 * hashCode) + mine.hashCode();
|
||||
return mine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
|
||||
return visitMessage((MessageLite) mine, (MessageLite) other);
|
||||
@ -2127,18 +2101,6 @@ public abstract class GeneratedMessageLite<
|
||||
return mine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other) {
|
||||
final int protoHash;
|
||||
if (mine != null) {
|
||||
protoHash = mine.hashCode();
|
||||
} else {
|
||||
protoHash = 37;
|
||||
}
|
||||
hashCode = (53 * hashCode) + protoHash;
|
||||
return mine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
|
||||
hashCode = (53 * hashCode) + mine.hashCode();
|
||||
@ -2281,13 +2243,6 @@ public abstract class GeneratedMessageLite<
|
||||
return other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitOneofLazyMessage(boolean minePresent, Object mine, Object other) {
|
||||
LazyFieldLite lazy = minePresent ? (LazyFieldLite) mine : new LazyFieldLite();
|
||||
lazy.merge((LazyFieldLite) other);
|
||||
return lazy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitOneofMessage(boolean minePresent, Object mine, Object other) {
|
||||
if (minePresent) {
|
||||
@ -2311,17 +2266,6 @@ public abstract class GeneratedMessageLite<
|
||||
return mine != null ? mine : other;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LazyFieldLite visitLazyMessage(LazyFieldLite mine, LazyFieldLite other) {
|
||||
if (other != null) {
|
||||
if (mine == null) {
|
||||
mine = new LazyFieldLite();
|
||||
}
|
||||
mine.merge(other);
|
||||
}
|
||||
return mine;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ProtobufList<T> visitList(ProtobufList<T> mine, ProtobufList<T> other) {
|
||||
int size = mine.size();
|
||||
|
@ -30,6 +30,8 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import static com.google.protobuf.Internal.checkNotNull;
|
||||
|
||||
import com.google.protobuf.Descriptors.Descriptor;
|
||||
import com.google.protobuf.Descriptors.EnumDescriptor;
|
||||
import com.google.protobuf.Descriptors.EnumValueDescriptor;
|
||||
@ -47,7 +49,6 @@ import com.google.protobuf.Descriptors.OneofDescriptor;
|
||||
// to be able to use GeneratedMessage.GeneratedExtension. The GeneratedExtension definition in
|
||||
// this file is also excluded from opensource to avoid conflict.
|
||||
import com.google.protobuf.GeneratedMessage.GeneratedExtension;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectStreamException;
|
||||
@ -277,13 +278,30 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
|
||||
/**
|
||||
* Called by subclasses to parse an unknown field.
|
||||
*
|
||||
* @return {@code true} unless the tag is an end-group tag.
|
||||
*/
|
||||
protected boolean parseUnknownField(
|
||||
CodedInputStream input,
|
||||
UnknownFieldSet.Builder unknownFields,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
int tag) throws IOException {
|
||||
int tag)
|
||||
throws IOException {
|
||||
if (input.shouldDiscardUnknownFields()) {
|
||||
return input.skipField(tag);
|
||||
}
|
||||
return unknownFields.mergeFieldFrom(tag, input);
|
||||
}
|
||||
|
||||
protected boolean parseUnknownFieldProto3(
|
||||
CodedInputStream input,
|
||||
UnknownFieldSet.Builder unknownFields,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
int tag)
|
||||
throws IOException {
|
||||
if (input.shouldDiscardUnknownFieldsProto3()) {
|
||||
return input.skipField(tag);
|
||||
}
|
||||
return unknownFields.mergeFieldFrom(tag, input);
|
||||
}
|
||||
|
||||
@ -619,15 +637,22 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
protected BuilderType setUnknownFieldsProto3(final UnknownFieldSet unknownFields) {
|
||||
if (CodedInputStream.getProto3DiscardUnknownFieldsDefault()) {
|
||||
return (BuilderType) this;
|
||||
}
|
||||
this.unknownFields = unknownFields;
|
||||
onChanged();
|
||||
return (BuilderType) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BuilderType mergeUnknownFields(
|
||||
final UnknownFieldSet unknownFields) {
|
||||
this.unknownFields =
|
||||
return setUnknownFields(
|
||||
UnknownFieldSet.newBuilder(this.unknownFields)
|
||||
.mergeFrom(unknownFields)
|
||||
.build();
|
||||
onChanged();
|
||||
return (BuilderType) this;
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -665,18 +690,6 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
return unknownFields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by subclasses to parse an unknown field.
|
||||
* @return {@code true} unless the tag is an end-group tag.
|
||||
*/
|
||||
protected boolean parseUnknownField(
|
||||
final CodedInputStream input,
|
||||
final UnknownFieldSet.Builder unknownFields,
|
||||
final ExtensionRegistryLite extensionRegistry,
|
||||
final int tag) throws IOException {
|
||||
return unknownFields.mergeFieldFrom(tag, input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link BuilderParent} for giving to our children. This
|
||||
* small inner class makes it so we don't publicly expose the BuilderParent
|
||||
@ -987,8 +1000,23 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
int tag) throws IOException {
|
||||
return MessageReflection.mergeFieldFrom(
|
||||
input, unknownFields, extensionRegistry, getDescriptorForType(),
|
||||
new MessageReflection.ExtensionAdapter(extensions), tag);
|
||||
input, input.shouldDiscardUnknownFields() ? null : unknownFields, extensionRegistry,
|
||||
getDescriptorForType(), new MessageReflection.ExtensionAdapter(extensions), tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean parseUnknownFieldProto3(
|
||||
CodedInputStream input,
|
||||
UnknownFieldSet.Builder unknownFields,
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
int tag) throws IOException {
|
||||
return MessageReflection.mergeFieldFrom(
|
||||
input,
|
||||
input.shouldDiscardUnknownFieldsProto3() ? null : unknownFields,
|
||||
extensionRegistry,
|
||||
getDescriptorForType(),
|
||||
new MessageReflection.ExtensionAdapter(extensions),
|
||||
tag);
|
||||
}
|
||||
|
||||
|
||||
@ -1458,21 +1486,6 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
return super.isInitialized() && extensionsAreInitialized();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by subclasses to parse an unknown field or an extension.
|
||||
* @return {@code true} unless the tag is an end-group tag.
|
||||
*/
|
||||
@Override
|
||||
protected boolean parseUnknownField(
|
||||
final CodedInputStream input,
|
||||
final UnknownFieldSet.Builder unknownFields,
|
||||
final ExtensionRegistryLite extensionRegistry,
|
||||
final int tag) throws IOException {
|
||||
return MessageReflection.mergeFieldFrom(
|
||||
input, unknownFields, extensionRegistry, getDescriptorForType(),
|
||||
new MessageReflection.BuilderAdapter(this), tag);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Reflection
|
||||
|
||||
@ -2277,7 +2290,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
public Object getRepeatedRaw(Builder builder, int index) {
|
||||
return getRepeated(builder, index);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setRepeated(Builder builder, int index, Object value) {
|
||||
getMutableMapField(builder).getMutableList().set(index, coerceType((Message) value));
|
||||
@ -2678,7 +2691,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
|
||||
return (Extension<MessageType, T>) extension;
|
||||
}
|
||||
|
||||
|
||||
protected static int computeStringSize(final int fieldNumber, final Object value) {
|
||||
if (value instanceof String) {
|
||||
return CodedOutputStream.computeStringSize(fieldNumber, (String) value);
|
||||
@ -2686,7 +2699,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
return CodedOutputStream.computeBytesSize(fieldNumber, (ByteString) value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static int computeStringSizeNoTag(final Object value) {
|
||||
if (value instanceof String) {
|
||||
return CodedOutputStream.computeStringSizeNoTag((String) value);
|
||||
@ -2694,7 +2707,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
return CodedOutputStream.computeBytesSizeNoTag((ByteString) value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static void writeString(
|
||||
CodedOutputStream output, final int fieldNumber, final Object value) throws IOException {
|
||||
if (value instanceof String) {
|
||||
@ -2703,7 +2716,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
|
||||
output.writeBytes(fieldNumber, (ByteString) value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected static void writeStringNoTag(
|
||||
CodedOutputStream output, final Object value) throws IOException {
|
||||
if (value instanceof String) {
|
||||
|
@ -414,9 +414,8 @@ public final class Internal {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An empty byte array constant used in generated code.
|
||||
*/
|
||||
|
||||
/** An empty byte array constant used in generated code. */
|
||||
public static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
|
||||
|
||||
/**
|
||||
|
@ -50,6 +50,10 @@ public class InvalidProtocolBufferException extends IOException {
|
||||
super(e.getMessage(), e);
|
||||
}
|
||||
|
||||
public InvalidProtocolBufferException(final String description, IOException e) {
|
||||
super(description, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches an unfinished message to the exception to support best-effort
|
||||
* parsing in {@code Parser} interface.
|
||||
|
@ -31,7 +31,6 @@
|
||||
package com.google.protobuf;
|
||||
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -714,12 +713,14 @@ class MessageReflection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a single field into MergeTarget. The target can be Message.Builder,
|
||||
* FieldSet or MutableMessage.
|
||||
* Parses a single field into MergeTarget. The target can be Message.Builder, FieldSet or
|
||||
* MutableMessage.
|
||||
*
|
||||
* Package-private because it is used by GeneratedMessage.ExtendableMessage.
|
||||
* <p>Package-private because it is used by GeneratedMessage.ExtendableMessage.
|
||||
*
|
||||
* @param tag The tag, which should have already been read.
|
||||
* @param unknownFields If not null, unknown fields will be merged to this {@link
|
||||
* UnknownFieldSet}, otherwise unknown fields will be discarded.
|
||||
* @return {@code true} unless the tag is an end-group tag.
|
||||
*/
|
||||
static boolean mergeFieldFrom(
|
||||
@ -728,7 +729,8 @@ class MessageReflection {
|
||||
ExtensionRegistryLite extensionRegistry,
|
||||
Descriptors.Descriptor type,
|
||||
MergeTarget target,
|
||||
int tag) throws IOException {
|
||||
int tag)
|
||||
throws IOException {
|
||||
if (type.getOptions().getMessageSetWireFormat() &&
|
||||
tag == WireFormat.MESSAGE_SET_ITEM_TAG) {
|
||||
mergeMessageSetExtensionFromCodedStream(
|
||||
@ -792,7 +794,11 @@ class MessageReflection {
|
||||
}
|
||||
|
||||
if (unknown) { // Unknown field or wrong wire type. Skip.
|
||||
return unknownFields.mergeFieldFrom(tag, input);
|
||||
if (unknownFields != null) {
|
||||
return unknownFields.mergeFieldFrom(tag, input);
|
||||
} else {
|
||||
return input.skipField(tag);
|
||||
}
|
||||
}
|
||||
|
||||
if (packed) {
|
||||
@ -844,7 +850,9 @@ class MessageReflection {
|
||||
// If the number isn't recognized as a valid value for this enum,
|
||||
// drop it.
|
||||
if (value == null) {
|
||||
unknownFields.mergeVarintField(fieldNumber, rawValue);
|
||||
if (unknownFields != null) {
|
||||
unknownFields.mergeVarintField(fieldNumber, rawValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -947,7 +955,7 @@ class MessageReflection {
|
||||
mergeMessageSetExtensionFromBytes(
|
||||
rawBytes, extension, extensionRegistry, target);
|
||||
} else { // We don't know how to parse this. Ignore it.
|
||||
if (rawBytes != null) {
|
||||
if (rawBytes != null && unknownFields != null) {
|
||||
unknownFields.mergeField(typeId, UnknownFieldSet.Field.newBuilder()
|
||||
.addLengthDelimited(rawBytes).build());
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ import com.google.protobuf.Descriptors.Descriptor;
|
||||
import com.google.protobuf.Descriptors.EnumDescriptor;
|
||||
import com.google.protobuf.Descriptors.EnumValueDescriptor;
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.CharBuffer;
|
||||
@ -56,14 +55,7 @@ import java.util.regex.Pattern;
|
||||
public final class TextFormat {
|
||||
private TextFormat() {}
|
||||
|
||||
private static final Logger logger =
|
||||
Logger.getLogger(TextFormat.class.getName());
|
||||
|
||||
private static final Printer DEFAULT_PRINTER = new Printer();
|
||||
private static final Printer SINGLE_LINE_PRINTER =
|
||||
(new Printer()).setSingleLineMode(true);
|
||||
private static final Printer UNICODE_PRINTER =
|
||||
(new Printer()).setEscapeNonAscii(false);
|
||||
private static final Logger logger = Logger.getLogger(TextFormat.class.getName());
|
||||
|
||||
/**
|
||||
* Outputs a textual representation of the Protocol Message supplied into
|
||||
@ -73,14 +65,14 @@ public final class TextFormat {
|
||||
public static void print(
|
||||
final MessageOrBuilder message, final Appendable output)
|
||||
throws IOException {
|
||||
DEFAULT_PRINTER.print(message, new TextGenerator(output));
|
||||
Printer.DEFAULT.print(message, multiLineOutput(output));
|
||||
}
|
||||
|
||||
/** Outputs a textual representation of {@code fields} to {@code output}. */
|
||||
public static void print(final UnknownFieldSet fields,
|
||||
final Appendable output)
|
||||
throws IOException {
|
||||
DEFAULT_PRINTER.printUnknownFields(fields, new TextGenerator(output));
|
||||
Printer.DEFAULT.printUnknownFields(fields, multiLineOutput(output));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,7 +82,7 @@ public final class TextFormat {
|
||||
public static void printUnicode(
|
||||
final MessageOrBuilder message, final Appendable output)
|
||||
throws IOException {
|
||||
UNICODE_PRINTER.print(message, new TextGenerator(output));
|
||||
Printer.UNICODE.print(message, multiLineOutput(output));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,7 +92,7 @@ public final class TextFormat {
|
||||
public static void printUnicode(final UnknownFieldSet fields,
|
||||
final Appendable output)
|
||||
throws IOException {
|
||||
UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(output));
|
||||
Printer.UNICODE.printUnknownFields(fields, multiLineOutput(output));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,10 +101,9 @@ public final class TextFormat {
|
||||
*/
|
||||
public static String shortDebugString(final MessageOrBuilder message) {
|
||||
try {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
SINGLE_LINE_PRINTER.print(message, new TextGenerator(sb));
|
||||
// Single line mode currently might have an extra space at the end.
|
||||
return sb.toString().trim();
|
||||
final StringBuilder text = new StringBuilder();
|
||||
Printer.DEFAULT.print(message, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
@ -125,11 +116,11 @@ public final class TextFormat {
|
||||
public static String shortDebugString(final FieldDescriptor field,
|
||||
final Object value) {
|
||||
try {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
SINGLE_LINE_PRINTER.printField(field, value, new TextGenerator(sb));
|
||||
return sb.toString().trim();
|
||||
final StringBuilder text = new StringBuilder();
|
||||
Printer.DEFAULT.printField(field, value, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,10 +130,9 @@ public final class TextFormat {
|
||||
*/
|
||||
public static String shortDebugString(final UnknownFieldSet fields) {
|
||||
try {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
SINGLE_LINE_PRINTER.printUnknownFields(fields, new TextGenerator(sb));
|
||||
// Single line mode currently might have an extra space at the end.
|
||||
return sb.toString().trim();
|
||||
final StringBuilder text = new StringBuilder();
|
||||
Printer.DEFAULT.printUnknownFields(fields, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
@ -183,7 +173,7 @@ public final class TextFormat {
|
||||
public static String printToUnicodeString(final MessageOrBuilder message) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
UNICODE_PRINTER.print(message, new TextGenerator(text));
|
||||
Printer.UNICODE.print(message, multiLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
@ -197,7 +187,7 @@ public final class TextFormat {
|
||||
public static String printToUnicodeString(final UnknownFieldSet fields) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
UNICODE_PRINTER.printUnknownFields(fields, new TextGenerator(text));
|
||||
Printer.UNICODE.printUnknownFields(fields, multiLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
@ -208,7 +198,7 @@ public final class TextFormat {
|
||||
final Object value,
|
||||
final Appendable output)
|
||||
throws IOException {
|
||||
DEFAULT_PRINTER.printField(field, value, new TextGenerator(output));
|
||||
Printer.DEFAULT.printField(field, value, multiLineOutput(output));
|
||||
}
|
||||
|
||||
public static String printFieldToString(final FieldDescriptor field,
|
||||
@ -222,6 +212,23 @@ public final class TextFormat {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a unicode textual representation of the value of given field value.
|
||||
*
|
||||
* <p>Same as {@code printFieldValue()}, except that non-ASCII characters in string type fields
|
||||
* are not escaped in backslash+octals.
|
||||
*
|
||||
* @param field the descriptor of the field
|
||||
* @param value the value of the field
|
||||
* @param output the output to which to append the formatted value
|
||||
* @throws ClassCastException if the value is not appropriate for the given field descriptor
|
||||
* @throws IOException if there is an exception writing to the output
|
||||
*/
|
||||
public static void printUnicodeFieldValue(
|
||||
final FieldDescriptor field, final Object value, final Appendable output) throws IOException {
|
||||
Printer.UNICODE.printFieldValue(field, value, multiLineOutput(output));
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a textual representation of the value of given field value.
|
||||
*
|
||||
@ -236,7 +243,7 @@ public final class TextFormat {
|
||||
final Object value,
|
||||
final Appendable output)
|
||||
throws IOException {
|
||||
DEFAULT_PRINTER.printFieldValue(field, value, new TextGenerator(output));
|
||||
Printer.DEFAULT.printFieldValue(field, value, multiLineOutput(output));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,7 +260,7 @@ public final class TextFormat {
|
||||
final Object value,
|
||||
final Appendable output)
|
||||
throws IOException {
|
||||
printUnknownFieldValue(tag, value, new TextGenerator(output));
|
||||
printUnknownFieldValue(tag, value, multiLineOutput(output));
|
||||
}
|
||||
|
||||
private static void printUnknownFieldValue(final int tag,
|
||||
@ -277,7 +284,7 @@ public final class TextFormat {
|
||||
generator.print("\"");
|
||||
break;
|
||||
case WireFormat.WIRETYPE_START_GROUP:
|
||||
DEFAULT_PRINTER.printUnknownFields((UnknownFieldSet) value, generator);
|
||||
Printer.DEFAULT.printUnknownFields((UnknownFieldSet) value, generator);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Bad tag: " + tag);
|
||||
@ -286,24 +293,16 @@ public final class TextFormat {
|
||||
|
||||
/** Helper class for converting protobufs to text. */
|
||||
private static final class Printer {
|
||||
/** Whether to omit newlines from the output. */
|
||||
boolean singleLineMode = false;
|
||||
// Printer instance which escapes non-ASCII characters.
|
||||
static final Printer DEFAULT = new Printer(true);
|
||||
// Printer instance which emits Unicode (it still escapes newlines and quotes in strings).
|
||||
static final Printer UNICODE = new Printer(false);
|
||||
|
||||
/** Whether to escape non ASCII characters with backslash and octal. */
|
||||
boolean escapeNonAscii = true;
|
||||
private final boolean escapeNonAscii;
|
||||
|
||||
private Printer() {}
|
||||
|
||||
/** Setter of singleLineMode */
|
||||
private Printer setSingleLineMode(boolean singleLineMode) {
|
||||
this.singleLineMode = singleLineMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Setter of escapeNonAscii */
|
||||
private Printer setEscapeNonAscii(boolean escapeNonAscii) {
|
||||
private Printer(boolean escapeNonAscii) {
|
||||
this.escapeNonAscii = escapeNonAscii;
|
||||
return this;
|
||||
}
|
||||
|
||||
private void print(
|
||||
@ -355,12 +354,9 @@ public final class TextFormat {
|
||||
}
|
||||
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
if (singleLineMode) {
|
||||
generator.print(" { ");
|
||||
} else {
|
||||
generator.print(" {\n");
|
||||
generator.indent();
|
||||
}
|
||||
generator.print(" {");
|
||||
generator.eol();
|
||||
generator.indent();
|
||||
} else {
|
||||
generator.print(": ");
|
||||
}
|
||||
@ -368,19 +364,10 @@ public final class TextFormat {
|
||||
printFieldValue(field, value, generator);
|
||||
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
if (singleLineMode) {
|
||||
generator.print("} ");
|
||||
} else {
|
||||
generator.outdent();
|
||||
generator.print("}\n");
|
||||
}
|
||||
} else {
|
||||
if (singleLineMode) {
|
||||
generator.print(" ");
|
||||
} else {
|
||||
generator.print("\n");
|
||||
}
|
||||
generator.outdent();
|
||||
generator.print("}");
|
||||
}
|
||||
generator.eol();
|
||||
}
|
||||
|
||||
private void printFieldValue(final FieldDescriptor field,
|
||||
@ -469,19 +456,13 @@ public final class TextFormat {
|
||||
field.getLengthDelimitedList(), generator);
|
||||
for (final UnknownFieldSet value : field.getGroupList()) {
|
||||
generator.print(entry.getKey().toString());
|
||||
if (singleLineMode) {
|
||||
generator.print(" { ");
|
||||
} else {
|
||||
generator.print(" {\n");
|
||||
generator.indent();
|
||||
}
|
||||
generator.print(" {");
|
||||
generator.eol();
|
||||
generator.indent();
|
||||
printUnknownFields(value, generator);
|
||||
if (singleLineMode) {
|
||||
generator.print("} ");
|
||||
} else {
|
||||
generator.outdent();
|
||||
generator.print("}\n");
|
||||
}
|
||||
generator.outdent();
|
||||
generator.print("}");
|
||||
generator.eol();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -495,7 +476,7 @@ public final class TextFormat {
|
||||
generator.print(String.valueOf(number));
|
||||
generator.print(": ");
|
||||
printUnknownFieldValue(wireType, value, generator);
|
||||
generator.print(singleLineMode ? " " : "\n");
|
||||
generator.eol();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -521,16 +502,29 @@ public final class TextFormat {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
private static TextGenerator multiLineOutput(Appendable output) {
|
||||
return new TextGenerator(output, false);
|
||||
}
|
||||
|
||||
private static TextGenerator singleLineOutput(Appendable output) {
|
||||
return new TextGenerator(output, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* An inner class for writing text to the output stream.
|
||||
*/
|
||||
private static final class TextGenerator {
|
||||
private final Appendable output;
|
||||
private final StringBuilder indent = new StringBuilder();
|
||||
private boolean atStartOfLine = true;
|
||||
private final boolean singleLineMode;
|
||||
// While technically we are "at the start of a line" at the very beginning of the output, all
|
||||
// we would do in response to this is emit the (zero length) indentation, so it has no effect.
|
||||
// Setting it false here does however suppress an unwanted leading space in single-line mode.
|
||||
private boolean atStartOfLine = false;
|
||||
|
||||
private TextGenerator(final Appendable output) {
|
||||
private TextGenerator(final Appendable output, boolean singleLineMode) {
|
||||
this.output = output;
|
||||
this.singleLineMode = singleLineMode;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -552,35 +546,31 @@ public final class TextFormat {
|
||||
throw new IllegalArgumentException(
|
||||
" Outdent() without matching Indent().");
|
||||
}
|
||||
indent.delete(length - 2, length);
|
||||
indent.setLength(length - 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print text to the output stream.
|
||||
* Print text to the output stream. Bare newlines are never expected to be passed to this
|
||||
* method; to indicate the end of a line, call "eol()".
|
||||
*/
|
||||
public void print(final CharSequence text) throws IOException {
|
||||
final int size = text.length();
|
||||
int pos = 0;
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (text.charAt(i) == '\n') {
|
||||
write(text.subSequence(pos, i + 1));
|
||||
pos = i + 1;
|
||||
atStartOfLine = true;
|
||||
}
|
||||
}
|
||||
write(text.subSequence(pos, size));
|
||||
}
|
||||
|
||||
private void write(final CharSequence data) throws IOException {
|
||||
if (data.length() == 0) {
|
||||
return;
|
||||
}
|
||||
if (atStartOfLine) {
|
||||
atStartOfLine = false;
|
||||
output.append(indent);
|
||||
output.append(singleLineMode ? " " : indent);
|
||||
}
|
||||
output.append(data);
|
||||
output.append(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Signifies reaching the "end of the current line" in the output. In single-line mode, this
|
||||
* does not result in a newline being emitted, but ensures that a separating space is written
|
||||
* before the next output.
|
||||
*/
|
||||
public void eol() throws IOException {
|
||||
if (!singleLineMode) {
|
||||
output.append("\n");
|
||||
}
|
||||
atStartOfLine = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1469,9 +1459,15 @@ public final class TextFormat {
|
||||
extensionRegistry, name.toString());
|
||||
|
||||
if (extension == null) {
|
||||
unknownFields.add((tokenizer.getPreviousLine() + 1) + ":" +
|
||||
(tokenizer.getPreviousColumn() + 1) + ":\t" +
|
||||
type.getFullName() + ".[" + name + "]");
|
||||
unknownFields.add(
|
||||
(tokenizer.getPreviousLine() + 1)
|
||||
+ ":"
|
||||
+ (tokenizer.getPreviousColumn() + 1)
|
||||
+ ":\t"
|
||||
+ type.getFullName()
|
||||
+ ".["
|
||||
+ name
|
||||
+ "]");
|
||||
} else {
|
||||
if (extension.descriptor.getContainingType() != type) {
|
||||
throw tokenizer.parseExceptionPreviousToken(
|
||||
@ -1506,9 +1502,14 @@ public final class TextFormat {
|
||||
}
|
||||
|
||||
if (field == null) {
|
||||
unknownFields.add((tokenizer.getPreviousLine() + 1) + ":" +
|
||||
(tokenizer.getPreviousColumn() + 1) + ":\t" +
|
||||
type.getFullName() + "." + name);
|
||||
unknownFields.add(
|
||||
(tokenizer.getPreviousLine() + 1)
|
||||
+ ":"
|
||||
+ (tokenizer.getPreviousColumn() + 1)
|
||||
+ ":\t"
|
||||
+ type.getFullName()
|
||||
+ "."
|
||||
+ name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -715,7 +715,7 @@ public final class UnknownFieldSet implements MessageLite {
|
||||
* @see UnknownFieldSet
|
||||
*/
|
||||
public static final class Field {
|
||||
Field() {}
|
||||
private Field() {}
|
||||
|
||||
/** Construct a new {@link Builder}. */
|
||||
public static Builder newBuilder() {
|
||||
|
@ -47,8 +47,29 @@ final class UnsafeUtil {
|
||||
private static final boolean HAS_UNSAFE_BYTEBUFFER_OPERATIONS =
|
||||
supportsUnsafeByteBufferOperations();
|
||||
private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = supportsUnsafeArrayOperations();
|
||||
private static final boolean HAS_UNSAFE_COPY_MEMORY = supportsUnsafeCopyMemory();
|
||||
private static final long ARRAY_BASE_OFFSET = byteArrayBaseOffset();
|
||||
|
||||
private static final long BYTE_ARRAY_BASE_OFFSET = arrayBaseOffset(byte[].class);
|
||||
// Micro-optimization: we can assume a scale of 1 and skip the multiply
|
||||
// private static final long BYTE_ARRAY_INDEX_SCALE = 1;
|
||||
|
||||
private static final long BOOLEAN_ARRAY_BASE_OFFSET = arrayBaseOffset(boolean[].class);
|
||||
private static final long BOOLEAN_ARRAY_INDEX_SCALE = arrayIndexScale(boolean[].class);
|
||||
|
||||
private static final long INT_ARRAY_BASE_OFFSET = arrayBaseOffset(int[].class);
|
||||
private static final long INT_ARRAY_INDEX_SCALE = arrayIndexScale(int[].class);
|
||||
|
||||
private static final long LONG_ARRAY_BASE_OFFSET = arrayBaseOffset(long[].class);
|
||||
private static final long LONG_ARRAY_INDEX_SCALE = arrayIndexScale(long[].class);
|
||||
|
||||
private static final long FLOAT_ARRAY_BASE_OFFSET = arrayBaseOffset(float[].class);
|
||||
private static final long FLOAT_ARRAY_INDEX_SCALE = arrayIndexScale(float[].class);
|
||||
|
||||
private static final long DOUBLE_ARRAY_BASE_OFFSET = arrayBaseOffset(double[].class);
|
||||
private static final long DOUBLE_ARRAY_INDEX_SCALE = arrayIndexScale(double[].class);
|
||||
|
||||
private static final long OBJECT_ARRAY_BASE_OFFSET = arrayBaseOffset(Object[].class);
|
||||
private static final long OBJECT_ARRAY_INDEX_SCALE = arrayIndexScale(Object[].class);
|
||||
|
||||
private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(bufferAddressField());
|
||||
|
||||
private UnsafeUtil() {}
|
||||
@ -57,10 +78,6 @@ final class UnsafeUtil {
|
||||
return HAS_UNSAFE_ARRAY_OPERATIONS;
|
||||
}
|
||||
|
||||
static boolean hasUnsafeCopyMemory() {
|
||||
return HAS_UNSAFE_COPY_MEMORY;
|
||||
}
|
||||
|
||||
static boolean hasUnsafeByteBufferOperations() {
|
||||
return HAS_UNSAFE_BYTEBUFFER_OPERATIONS;
|
||||
}
|
||||
@ -69,8 +86,12 @@ final class UnsafeUtil {
|
||||
return MEMORY_ACCESSOR.objectFieldOffset(field);
|
||||
}
|
||||
|
||||
static long getArrayBaseOffset() {
|
||||
return ARRAY_BASE_OFFSET;
|
||||
private static int arrayBaseOffset(Class<?> clazz) {
|
||||
return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayBaseOffset(clazz) : -1;
|
||||
}
|
||||
|
||||
private static int arrayIndexScale(Class<?> clazz) {
|
||||
return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayIndexScale(clazz) : -1;
|
||||
}
|
||||
|
||||
static byte getByte(Object target, long offset) {
|
||||
@ -129,9 +150,82 @@ final class UnsafeUtil {
|
||||
MEMORY_ACCESSOR.putObject(target, offset, value);
|
||||
}
|
||||
|
||||
static void copyMemory(
|
||||
Object src, long srcOffset, Object target, long targetOffset, long length) {
|
||||
MEMORY_ACCESSOR.copyMemory(src, srcOffset, target, targetOffset, length);
|
||||
static byte getByte(byte[] target, long index) {
|
||||
return MEMORY_ACCESSOR.getByte(target, BYTE_ARRAY_BASE_OFFSET + index);
|
||||
}
|
||||
|
||||
static void putByte(byte[] target, long index, byte value) {
|
||||
MEMORY_ACCESSOR.putByte(target, BYTE_ARRAY_BASE_OFFSET + index, value);
|
||||
}
|
||||
|
||||
static int getInt(int[] target, long index) {
|
||||
return MEMORY_ACCESSOR.getInt(target, INT_ARRAY_BASE_OFFSET + (index * INT_ARRAY_INDEX_SCALE));
|
||||
}
|
||||
|
||||
static void putInt(int[] target, long index, int value) {
|
||||
MEMORY_ACCESSOR.putInt(target, INT_ARRAY_BASE_OFFSET + (index * INT_ARRAY_INDEX_SCALE), value);
|
||||
}
|
||||
|
||||
static long getLong(long[] target, long index) {
|
||||
return MEMORY_ACCESSOR.getLong(
|
||||
target, LONG_ARRAY_BASE_OFFSET + (index * LONG_ARRAY_INDEX_SCALE));
|
||||
}
|
||||
|
||||
static void putLong(long[] target, long index, long value) {
|
||||
MEMORY_ACCESSOR.putLong(
|
||||
target, LONG_ARRAY_BASE_OFFSET + (index * LONG_ARRAY_INDEX_SCALE), value);
|
||||
}
|
||||
|
||||
static boolean getBoolean(boolean[] target, long index) {
|
||||
return MEMORY_ACCESSOR.getBoolean(
|
||||
target, BOOLEAN_ARRAY_BASE_OFFSET + (index * BOOLEAN_ARRAY_INDEX_SCALE));
|
||||
}
|
||||
|
||||
static void putBoolean(boolean[] target, long index, boolean value) {
|
||||
MEMORY_ACCESSOR.putBoolean(
|
||||
target, BOOLEAN_ARRAY_BASE_OFFSET + (index * BOOLEAN_ARRAY_INDEX_SCALE), value);
|
||||
}
|
||||
|
||||
static float getFloat(float[] target, long index) {
|
||||
return MEMORY_ACCESSOR.getFloat(
|
||||
target, FLOAT_ARRAY_BASE_OFFSET + (index * FLOAT_ARRAY_INDEX_SCALE));
|
||||
}
|
||||
|
||||
static void putFloat(float[] target, long index, float value) {
|
||||
MEMORY_ACCESSOR.putFloat(
|
||||
target, FLOAT_ARRAY_BASE_OFFSET + (index * FLOAT_ARRAY_INDEX_SCALE), value);
|
||||
}
|
||||
|
||||
static double getDouble(double[] target, long index) {
|
||||
return MEMORY_ACCESSOR.getDouble(
|
||||
target, DOUBLE_ARRAY_BASE_OFFSET + (index * DOUBLE_ARRAY_INDEX_SCALE));
|
||||
}
|
||||
|
||||
static void putDouble(double[] target, long index, double value) {
|
||||
MEMORY_ACCESSOR.putDouble(
|
||||
target, DOUBLE_ARRAY_BASE_OFFSET + (index * DOUBLE_ARRAY_INDEX_SCALE), value);
|
||||
}
|
||||
|
||||
static Object getObject(Object[] target, long index) {
|
||||
return MEMORY_ACCESSOR.getObject(
|
||||
target, OBJECT_ARRAY_BASE_OFFSET + (index * OBJECT_ARRAY_INDEX_SCALE));
|
||||
}
|
||||
|
||||
static void putObject(Object[] target, long index, Object value) {
|
||||
MEMORY_ACCESSOR.putObject(
|
||||
target, OBJECT_ARRAY_BASE_OFFSET + (index * OBJECT_ARRAY_INDEX_SCALE), value);
|
||||
}
|
||||
|
||||
static void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
|
||||
MEMORY_ACCESSOR.copyMemory(src, srcIndex, targetOffset, length);
|
||||
}
|
||||
|
||||
static void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
|
||||
MEMORY_ACCESSOR.copyMemory(srcOffset, target, targetIndex, length);
|
||||
}
|
||||
|
||||
static void copyMemory(byte[] src, long srcIndex, byte[] target, long targetIndex, long length) {
|
||||
System.arraycopy(src, (int) srcIndex, target, (int) targetIndex, (int) length);
|
||||
}
|
||||
|
||||
static byte getByte(long address) {
|
||||
@ -221,6 +315,7 @@ final class UnsafeUtil {
|
||||
Class<?> clazz = UNSAFE.getClass();
|
||||
clazz.getMethod("objectFieldOffset", Field.class);
|
||||
clazz.getMethod("arrayBaseOffset", Class.class);
|
||||
clazz.getMethod("arrayIndexScale", Class.class);
|
||||
clazz.getMethod("getInt", Object.class, long.class);
|
||||
clazz.getMethod("putInt", Object.class, long.class, int.class);
|
||||
clazz.getMethod("getLong", Object.class, long.class);
|
||||
@ -245,27 +340,6 @@ final class UnsafeUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether or not unsafe copyMemory(object, long, object, long, long) operations are
|
||||
* supported on this platform.
|
||||
*/
|
||||
private static boolean supportsUnsafeCopyMemory() {
|
||||
if (UNSAFE == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
Class<?> clazz = UNSAFE.getClass();
|
||||
clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class);
|
||||
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
logger.log(
|
||||
Level.WARNING,
|
||||
"copyMemory is missing from platform - proto runtime falling back to safer methods.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean supportsUnsafeByteBufferOperations() {
|
||||
if (UNSAFE == null) {
|
||||
return false;
|
||||
@ -283,6 +357,7 @@ final class UnsafeUtil {
|
||||
clazz.getMethod("getLong", long.class);
|
||||
clazz.getMethod("putLong", long.class, long.class);
|
||||
clazz.getMethod("copyMemory", long.class, long.class, long.class);
|
||||
clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class);
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
logger.log(
|
||||
@ -307,13 +382,6 @@ final class UnsafeUtil {
|
||||
return field(Buffer.class, "address");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base offset for byte arrays, or {@code -1} if {@code sun.misc.Unsafe} is not available.
|
||||
*/
|
||||
private static int byteArrayBaseOffset() {
|
||||
return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayBaseOffset(byte[].class) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the offset of the provided field, or {@code -1} if {@code sun.misc.Unsafe} is not
|
||||
* available.
|
||||
@ -394,6 +462,10 @@ final class UnsafeUtil {
|
||||
return unsafe.arrayBaseOffset(clazz);
|
||||
}
|
||||
|
||||
public final int arrayIndexScale(Class<?> clazz) {
|
||||
return unsafe.arrayIndexScale(clazz);
|
||||
}
|
||||
|
||||
public abstract byte getByte(long address);
|
||||
|
||||
public abstract void putByte(long address, byte value);
|
||||
@ -408,10 +480,11 @@ final class UnsafeUtil {
|
||||
|
||||
public abstract void copyMemory(long srcAddress, long targetAddress, long length);
|
||||
|
||||
public abstract void copyMemory(
|
||||
Object src, long srcOffset, Object target, long targetOffset, long length);
|
||||
|
||||
public abstract Object getStaticObject(Field field);
|
||||
|
||||
public abstract void copyMemory(long srcOffset, byte[] target, long targetIndex, long length);
|
||||
|
||||
public abstract void copyMemory(byte[] src, long srcIndex, long targetOffset, long length);
|
||||
}
|
||||
|
||||
private static final class JvmMemoryAccessor extends MemoryAccessor {
|
||||
@ -490,16 +563,20 @@ final class UnsafeUtil {
|
||||
unsafe.putDouble(target, offset, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyMemory(
|
||||
Object src, long srcOffset, Object target, long targetOffset, long length) {
|
||||
unsafe.copyMemory(src, srcOffset, target, targetOffset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyMemory(long srcAddress, long targetAddress, long length) {
|
||||
unsafe.copyMemory(srcAddress, targetAddress, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyMemory(long srcOffset, byte[] target, long targetIndex, long length) {
|
||||
unsafe.copyMemory(null, srcOffset, target, BYTE_ARRAY_BASE_OFFSET + targetIndex, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyMemory(byte[] src, long srcIndex, long targetOffset, long length) {
|
||||
unsafe.copyMemory(src, BYTE_ARRAY_BASE_OFFSET + srcIndex, null, targetOffset, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getStaticObject(Field field) {
|
||||
|
@ -31,7 +31,6 @@
|
||||
package com.google.protobuf;
|
||||
|
||||
import static com.google.protobuf.UnsafeUtil.addressOffset;
|
||||
import static com.google.protobuf.UnsafeUtil.getArrayBaseOffset;
|
||||
import static com.google.protobuf.UnsafeUtil.hasUnsafeArrayOperations;
|
||||
import static com.google.protobuf.UnsafeUtil.hasUnsafeByteBufferOperations;
|
||||
import static java.lang.Character.MAX_SURROGATE;
|
||||
@ -1001,8 +1000,8 @@ final class Utf8 {
|
||||
throw new ArrayIndexOutOfBoundsException(
|
||||
String.format("Array length=%d, index=%d, limit=%d", bytes.length, index, limit));
|
||||
}
|
||||
long offset = getArrayBaseOffset() + index;
|
||||
final long offsetLimit = getArrayBaseOffset() + limit;
|
||||
long offset = index;
|
||||
final long offsetLimit = limit;
|
||||
if (state != COMPLETE) {
|
||||
// The previous decoding operation was incomplete (or malformed).
|
||||
// We look for a well-formed sequence consisting of bytes from
|
||||
@ -1187,7 +1186,7 @@ final class Utf8 {
|
||||
|
||||
@Override
|
||||
int encodeUtf8(final CharSequence in, final byte[] out, final int offset, final int length) {
|
||||
long outIx = getArrayBaseOffset() + offset;
|
||||
long outIx = offset;
|
||||
final long outLimit = outIx + length;
|
||||
final int inLimit = in.length();
|
||||
if (inLimit > length || out.length - length < offset) {
|
||||
@ -1204,7 +1203,7 @@ final class Utf8 {
|
||||
}
|
||||
if (inIx == inLimit) {
|
||||
// We're done, it was ASCII encoded.
|
||||
return (int) (outIx - getArrayBaseOffset());
|
||||
return (int) outIx;
|
||||
}
|
||||
|
||||
for (char c; inIx < inLimit; ++inIx) {
|
||||
@ -1243,7 +1242,7 @@ final class Utf8 {
|
||||
}
|
||||
|
||||
// All bytes have been encoded.
|
||||
return (int) (outIx - getArrayBaseOffset());
|
||||
return (int) outIx;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1321,31 +1320,17 @@ final class Utf8 {
|
||||
*/
|
||||
private static int unsafeEstimateConsecutiveAscii(
|
||||
byte[] bytes, long offset, final int maxChars) {
|
||||
int remaining = maxChars;
|
||||
if (remaining < UNSAFE_COUNT_ASCII_THRESHOLD) {
|
||||
if (maxChars < UNSAFE_COUNT_ASCII_THRESHOLD) {
|
||||
// Don't bother with small strings.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read bytes until 8-byte aligned so that we can read longs in the loop below.
|
||||
// Byte arrays are already either 8 or 16-byte aligned, so we just need to make sure that
|
||||
// the index (relative to the start of the array) is also 8-byte aligned. We do this by
|
||||
// ANDing the index with 7 to determine the number of bytes that need to be read before
|
||||
// we're 8-byte aligned.
|
||||
final int unaligned = 8 - ((int) offset & 7);
|
||||
for (int j = unaligned; j > 0; j--) {
|
||||
for (int i = 0; i < maxChars; i++) {
|
||||
if (UnsafeUtil.getByte(bytes, offset++) < 0) {
|
||||
return unaligned - j;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// This simple loop stops when we encounter a byte >= 0x80 (i.e. non-ASCII).
|
||||
// To speed things up further, we're reading longs instead of bytes so we use a mask to
|
||||
// determine if any byte in the current long is non-ASCII.
|
||||
remaining -= unaligned;
|
||||
for (; remaining >= 8 && (UnsafeUtil.getLong(bytes, offset) & ASCII_MASK_LONG) == 0;
|
||||
offset += 8, remaining -= 8) {}
|
||||
return maxChars - remaining;
|
||||
return maxChars;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -47,8 +47,10 @@ public final class WireFormat {
|
||||
// Do not allow instantiation.
|
||||
private WireFormat() {}
|
||||
|
||||
static final int FIXED_32_SIZE = 4;
|
||||
static final int FIXED_64_SIZE = 8;
|
||||
static final int FIXED32_SIZE = 4;
|
||||
static final int FIXED64_SIZE = 8;
|
||||
static final int MAX_VARINT32_SIZE = 5;
|
||||
static final int MAX_VARINT64_SIZE = 10;
|
||||
static final int MAX_VARINT_SIZE = 10;
|
||||
|
||||
public static final int WIRETYPE_VARINT = 0;
|
||||
|
@ -41,6 +41,7 @@ import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -613,6 +614,82 @@ public class CodedInputStreamTest extends TestCase {
|
||||
checkSizeLimitExceeded(expected);
|
||||
}
|
||||
}
|
||||
|
||||
public void testRefillBufferWithCorrectSize() throws Exception {
|
||||
// NOTE: refillBuffer only applies to the stream-backed CIS.
|
||||
byte[] bytes = "123456789".getBytes("UTF-8");
|
||||
ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
|
||||
CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length);
|
||||
|
||||
int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
|
||||
output.writeRawVarint32(tag);
|
||||
output.writeRawVarint32(bytes.length);
|
||||
output.writeRawBytes(bytes);
|
||||
output.writeRawVarint32(tag);
|
||||
output.writeRawVarint32(bytes.length);
|
||||
output.writeRawBytes(bytes);
|
||||
output.writeRawByte(4);
|
||||
output.flush();
|
||||
|
||||
// Input is two string with length 9 and one raw byte.
|
||||
byte[] rawInput = rawOutput.toByteArray();
|
||||
for (int inputStreamBufferLength = 8;
|
||||
inputStreamBufferLength <= rawInput.length + 1; inputStreamBufferLength++) {
|
||||
CodedInputStream input = CodedInputStream.newInstance(
|
||||
new ByteArrayInputStream(rawInput), inputStreamBufferLength);
|
||||
input.setSizeLimit(rawInput.length - 1);
|
||||
input.readString();
|
||||
input.readString();
|
||||
try {
|
||||
input.readRawByte(); // Hits limit.
|
||||
fail("Should have thrown an exception!");
|
||||
} catch (InvalidProtocolBufferException expected) {
|
||||
checkSizeLimitExceeded(expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void testIsAtEnd() throws Exception {
|
||||
CodedInputStream input = CodedInputStream.newInstance(
|
||||
new ByteArrayInputStream(new byte[5]));
|
||||
try {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
assertEquals(false, input.isAtEnd());
|
||||
input.readRawByte();
|
||||
}
|
||||
assertEquals(true, input.isAtEnd());
|
||||
} catch (Exception e) {
|
||||
fail("Catch exception in the testIsAtEnd");
|
||||
}
|
||||
}
|
||||
|
||||
public void testCurrentLimitExceeded() throws Exception {
|
||||
byte[] bytes = "123456789".getBytes("UTF-8");
|
||||
ByteArrayOutputStream rawOutput = new ByteArrayOutputStream();
|
||||
CodedOutputStream output = CodedOutputStream.newInstance(rawOutput, bytes.length);
|
||||
|
||||
int tag = WireFormat.makeTag(1, WireFormat.WIRETYPE_LENGTH_DELIMITED);
|
||||
output.writeRawVarint32(tag);
|
||||
output.writeRawVarint32(bytes.length);
|
||||
output.writeRawBytes(bytes);
|
||||
output.flush();
|
||||
|
||||
byte[] rawInput = rawOutput.toByteArray();
|
||||
CodedInputStream input = CodedInputStream.newInstance(
|
||||
new ByteArrayInputStream(rawInput));
|
||||
// The length of the whole rawInput
|
||||
input.setSizeLimit(11);
|
||||
// Some number that is smaller than the rawInput's length
|
||||
// but larger than 2
|
||||
input.pushLimit(5);
|
||||
try {
|
||||
input.readString();
|
||||
fail("Should have thrown an exception");
|
||||
} catch (InvalidProtocolBufferException expected) {
|
||||
assertEquals(expected.getMessage(),
|
||||
InvalidProtocolBufferException.truncatedMessage().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testSizeLimitMultipleMessages() throws Exception {
|
||||
// NOTE: Size limit only applies to the stream-backed CIS.
|
||||
@ -807,6 +884,52 @@ public class CodedInputStreamTest extends TestCase {
|
||||
}
|
||||
}
|
||||
|
||||
public void testReadLargeByteStringFromInputStream() throws Exception {
|
||||
byte[] bytes = new byte[1024 * 1024];
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = (byte) (i & 0xFF);
|
||||
}
|
||||
ByteString.Output rawOutput = ByteString.newOutput();
|
||||
CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
|
||||
output.writeRawVarint32(bytes.length);
|
||||
output.writeRawBytes(bytes);
|
||||
output.flush();
|
||||
byte[] data = rawOutput.toByteString().toByteArray();
|
||||
|
||||
CodedInputStream input = CodedInputStream.newInstance(
|
||||
new ByteArrayInputStream(data) {
|
||||
@Override
|
||||
public synchronized int available() {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
ByteString result = input.readBytes();
|
||||
assertEquals(ByteString.copyFrom(bytes), result);
|
||||
}
|
||||
|
||||
public void testReadLargeByteArrayFromInputStream() throws Exception {
|
||||
byte[] bytes = new byte[1024 * 1024];
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
bytes[i] = (byte) (i & 0xFF);
|
||||
}
|
||||
ByteString.Output rawOutput = ByteString.newOutput();
|
||||
CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
|
||||
output.writeRawVarint32(bytes.length);
|
||||
output.writeRawBytes(bytes);
|
||||
output.flush();
|
||||
byte[] data = rawOutput.toByteString().toByteArray();
|
||||
|
||||
CodedInputStream input = CodedInputStream.newInstance(
|
||||
new ByteArrayInputStream(data) {
|
||||
@Override
|
||||
public synchronized int available() {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
byte[] result = input.readByteArray();
|
||||
assertTrue(Arrays.equals(bytes, result));
|
||||
}
|
||||
|
||||
public void testReadByteBuffer() throws Exception {
|
||||
ByteString.Output rawOutput = ByteString.newOutput();
|
||||
CodedOutputStream output = CodedOutputStream.newInstance(rawOutput);
|
||||
|
@ -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 protobuf_unittest.UnittestProto;
|
||||
import proto3_unittest.UnittestProto3;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
/** Unit tests for discard or preserve unknown fields. */
|
||||
@RunWith(JUnit4.class)
|
||||
public class DiscardUnknownFieldsTest {
|
||||
@Test
|
||||
public void testProto2() throws Exception {
|
||||
testProto2Message(
|
||||
UnittestProto.TestEmptyMessage.getDefaultInstance());
|
||||
testProto2Message(
|
||||
UnittestProto.TestEmptyMessageWithExtensions.getDefaultInstance());
|
||||
testProto2Message(
|
||||
DynamicMessage.getDefaultInstance(UnittestProto.TestEmptyMessage.getDescriptor()));
|
||||
testProto2Message(
|
||||
DynamicMessage.getDefaultInstance(
|
||||
UnittestProto.TestEmptyMessageWithExtensions.getDescriptor()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProto3() throws Exception {
|
||||
testProto3Message(UnittestProto3.TestEmptyMessage.getDefaultInstance());
|
||||
testProto3Message(
|
||||
DynamicMessage.getDefaultInstance(UnittestProto3.TestEmptyMessage.getDescriptor()));
|
||||
}
|
||||
|
||||
private static void testProto2Message(Message message) throws Exception {
|
||||
assertUnknownFieldsDefaultPreserved(message);
|
||||
assertUnknownFieldsExplicitlyDiscarded(message);
|
||||
assertReuseCodedInputStreamPreserve(message);
|
||||
assertUnknownFieldsInUnknownFieldSetArePreserve(message);
|
||||
}
|
||||
|
||||
private static void testProto3Message(Message message) throws Exception {
|
||||
CodedInputStream.setProto3KeepUnknownsByDefaultForTest();
|
||||
assertUnknownFieldsDefaultPreserved(message);
|
||||
assertUnknownFieldsExplicitlyDiscarded(message);
|
||||
assertReuseCodedInputStreamPreserve(message);
|
||||
assertUnknownFieldsInUnknownFieldSetArePreserve(message);
|
||||
CodedInputStream.setProto3DiscardUnknownsByDefaultForTest();
|
||||
assertUnknownFieldsDefaultDiscarded(message);
|
||||
assertUnknownFieldsExplicitlyDiscarded(message);
|
||||
assertUnknownFieldsInUnknownFieldSetAreDiscarded(message);
|
||||
}
|
||||
|
||||
private static void assertReuseCodedInputStreamPreserve(Message message) throws Exception {
|
||||
final int messageSize = payload.size();
|
||||
byte[] copied = new byte[messageSize * 2];
|
||||
payload.copyTo(copied, 0);
|
||||
payload.copyTo(copied, messageSize);
|
||||
CodedInputStream input = CodedInputStream.newInstance(copied);
|
||||
{
|
||||
// Use DiscardUnknownFieldsParser to parse the first payload.
|
||||
int oldLimit = input.pushLimit(messageSize);
|
||||
Message parsed = DiscardUnknownFieldsParser.wrap(message.getParserForType()).parseFrom(input);
|
||||
assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize());
|
||||
input.popLimit(oldLimit);
|
||||
}
|
||||
{
|
||||
// Use the normal parser to parse the remaining payload should have unknown fields preserved.
|
||||
Message parsed = message.getParserForType().parseFrom(input);
|
||||
assertEquals(message.getClass().getName(), payload, parsed.toByteString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Message.Builder#setUnknownFields(UnknownFieldSet)} and {@link
|
||||
* Message.Builder#mergeUnknownFields(UnknownFieldSet)} should preserve the unknown fields.
|
||||
*/
|
||||
private static void assertUnknownFieldsInUnknownFieldSetArePreserve(Message message)
|
||||
throws Exception {
|
||||
UnknownFieldSet unknownFields = UnknownFieldSet.newBuilder().mergeFrom(payload).build();
|
||||
Message built = message.newBuilderForType().setUnknownFields(unknownFields).build();
|
||||
assertEquals(message.getClass().getName(), payload, built.toByteString());
|
||||
|
||||
}
|
||||
/**
|
||||
* {@link Message.Builder#setUnknownFields(UnknownFieldSet)} and {@link
|
||||
* Message.Builder#mergeUnknownFields(UnknownFieldSet)} should discard the unknown fields.
|
||||
*/
|
||||
private static void assertUnknownFieldsInUnknownFieldSetAreDiscarded(Message message)
|
||||
throws Exception {
|
||||
UnknownFieldSet unknownFields = UnknownFieldSet.newBuilder().mergeFrom(payload).build();
|
||||
Message built = message.newBuilderForType().setUnknownFields(unknownFields).build();
|
||||
assertEquals(message.getClass().getName(), 0, built.getSerializedSize());
|
||||
}
|
||||
|
||||
private static void assertUnknownFieldsDefaultPreserved(MessageLite message) throws Exception {
|
||||
{
|
||||
MessageLite parsed = message.getParserForType().parseFrom(payload);
|
||||
assertEquals(message.getClass().getName(), payload, parsed.toByteString());
|
||||
}
|
||||
|
||||
{
|
||||
MessageLite parsed = message.newBuilderForType().mergeFrom(payload).build();
|
||||
assertEquals(message.getClass().getName(), payload, parsed.toByteString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertUnknownFieldsDefaultDiscarded(MessageLite message) throws Exception {
|
||||
{
|
||||
MessageLite parsed = message.getParserForType().parseFrom(payload);
|
||||
assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize());
|
||||
}
|
||||
|
||||
{
|
||||
MessageLite parsed = message.newBuilderForType().mergeFrom(payload).build();
|
||||
assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize());
|
||||
}
|
||||
}
|
||||
|
||||
private static void assertUnknownFieldsExplicitlyDiscarded(Message message) throws Exception {
|
||||
Message parsed =
|
||||
DiscardUnknownFieldsParser.wrap(message.getParserForType()).parseFrom(payload);
|
||||
assertEquals(message.getClass().getName(), 0, parsed.getSerializedSize());
|
||||
}
|
||||
|
||||
private static final ByteString payload =
|
||||
TestUtilLite.getAllLiteSetBuilder().build().toByteString();
|
||||
}
|
@ -108,7 +108,7 @@ public class FieldPresenceTest extends TestCase {
|
||||
assertFalse(TestAllTypes.newBuilder().build().hasOptionalNestedMessage());
|
||||
assertFalse(TestAllTypes.newBuilder().hasOptionalNestedMessage());
|
||||
|
||||
// oneof fields don't have hasFoo() methods (even for message types).
|
||||
// oneof fields don't have hasFoo() methods for non-message types.
|
||||
assertHasMethodRemoved(
|
||||
UnittestProto.TestAllTypes.class,
|
||||
TestAllTypes.class,
|
||||
@ -121,10 +121,8 @@ public class FieldPresenceTest extends TestCase {
|
||||
UnittestProto.TestAllTypes.class,
|
||||
TestAllTypes.class,
|
||||
"OneofBytes");
|
||||
assertHasMethodRemoved(
|
||||
UnittestProto.TestAllTypes.class,
|
||||
TestAllTypes.class,
|
||||
"OneofNestedMessage");
|
||||
assertFalse(TestAllTypes.newBuilder().build().hasOneofNestedMessage());
|
||||
assertFalse(TestAllTypes.newBuilder().hasOneofNestedMessage());
|
||||
|
||||
assertHasMethodRemoved(
|
||||
UnittestProto.TestAllTypes.Builder.class,
|
||||
@ -138,10 +136,6 @@ public class FieldPresenceTest extends TestCase {
|
||||
UnittestProto.TestAllTypes.Builder.class,
|
||||
TestAllTypes.Builder.class,
|
||||
"OneofBytes");
|
||||
assertHasMethodRemoved(
|
||||
UnittestProto.TestAllTypes.Builder.class,
|
||||
TestAllTypes.Builder.class,
|
||||
"OneofNestedMessage");
|
||||
}
|
||||
|
||||
public void testOneofEquals() throws Exception {
|
||||
|
@ -923,15 +923,9 @@ public class GeneratedMessageTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testEnumValues() {
|
||||
assertEquals(
|
||||
TestAllTypes.NestedEnum.BAR.getNumber(),
|
||||
TestAllTypes.NestedEnum.BAR_VALUE);
|
||||
assertEquals(
|
||||
TestAllTypes.NestedEnum.BAZ.getNumber(),
|
||||
TestAllTypes.NestedEnum.BAZ_VALUE);
|
||||
assertEquals(
|
||||
TestAllTypes.NestedEnum.FOO.getNumber(),
|
||||
TestAllTypes.NestedEnum.FOO_VALUE);
|
||||
assertEquals(TestAllTypes.NestedEnum.BAR_VALUE, TestAllTypes.NestedEnum.BAR.getNumber());
|
||||
assertEquals(TestAllTypes.NestedEnum.BAZ_VALUE, TestAllTypes.NestedEnum.BAZ.getNumber());
|
||||
assertEquals(TestAllTypes.NestedEnum.FOO_VALUE, TestAllTypes.NestedEnum.FOO.getNumber());
|
||||
}
|
||||
|
||||
public void testNonNestedExtensionInitialization() {
|
||||
@ -1319,51 +1313,51 @@ public class GeneratedMessageTest extends TestCase {
|
||||
assertFalse(builder.clearFooInt().hasFooInt());
|
||||
TestOneof2 message2 = builder.build();
|
||||
assertFalse(message2.hasFooInt());
|
||||
assertEquals(message2.getFooInt(), 0);
|
||||
assertEquals(0, message2.getFooInt());
|
||||
}
|
||||
|
||||
// Enum
|
||||
{
|
||||
TestOneof2.Builder builder = TestOneof2.newBuilder();
|
||||
assertEquals(builder.getFooEnum(), TestOneof2.NestedEnum.FOO);
|
||||
assertEquals(TestOneof2.NestedEnum.FOO, builder.getFooEnum());
|
||||
assertTrue(builder.setFooEnum(TestOneof2.NestedEnum.BAR).hasFooEnum());
|
||||
assertEquals(builder.getFooEnum(), TestOneof2.NestedEnum.BAR);
|
||||
assertEquals(TestOneof2.NestedEnum.BAR, builder.getFooEnum());
|
||||
TestOneof2 message = builder.buildPartial();
|
||||
assertTrue(message.hasFooEnum());
|
||||
assertEquals(message.getFooEnum(), TestOneof2.NestedEnum.BAR);
|
||||
assertEquals(TestOneof2.NestedEnum.BAR, message.getFooEnum());
|
||||
|
||||
assertFalse(builder.clearFooEnum().hasFooEnum());
|
||||
TestOneof2 message2 = builder.build();
|
||||
assertFalse(message2.hasFooEnum());
|
||||
assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.FOO);
|
||||
assertEquals(TestOneof2.NestedEnum.FOO, message2.getFooEnum());
|
||||
}
|
||||
|
||||
// String
|
||||
{
|
||||
TestOneof2.Builder builder = TestOneof2.newBuilder();
|
||||
assertEquals(builder.getFooString(), "");
|
||||
assertEquals("", builder.getFooString());
|
||||
builder.setFooString("foo");
|
||||
assertTrue(builder.hasFooString());
|
||||
assertEquals(builder.getFooString(), "foo");
|
||||
assertEquals("foo", builder.getFooString());
|
||||
TestOneof2 message = builder.buildPartial();
|
||||
assertTrue(message.hasFooString());
|
||||
assertEquals(message.getFooString(), "foo");
|
||||
assertEquals("foo", message.getFooString());
|
||||
assertEquals(message.getFooStringBytes(), TestUtil.toBytes("foo"));
|
||||
|
||||
assertFalse(builder.clearFooString().hasFooString());
|
||||
TestOneof2 message2 = builder.buildPartial();
|
||||
assertFalse(message2.hasFooString());
|
||||
assertEquals(message2.getFooString(), "");
|
||||
assertEquals("", message2.getFooString());
|
||||
assertEquals(message2.getFooStringBytes(), TestUtil.toBytes(""));
|
||||
|
||||
// Get method should not change the oneof value.
|
||||
builder.setFooInt(123);
|
||||
assertEquals(builder.getFooString(), "");
|
||||
assertEquals("", builder.getFooString());
|
||||
assertEquals(builder.getFooStringBytes(), TestUtil.toBytes(""));
|
||||
assertEquals(123, builder.getFooInt());
|
||||
|
||||
message = builder.build();
|
||||
assertEquals(message.getFooString(), "");
|
||||
assertEquals("", message.getFooString());
|
||||
assertEquals(message.getFooStringBytes(), TestUtil.toBytes(""));
|
||||
assertEquals(123, message.getFooInt());
|
||||
}
|
||||
@ -1371,38 +1365,38 @@ public class GeneratedMessageTest extends TestCase {
|
||||
// Cord
|
||||
{
|
||||
TestOneof2.Builder builder = TestOneof2.newBuilder();
|
||||
assertEquals(builder.getFooCord(), "");
|
||||
assertEquals("", builder.getFooCord());
|
||||
builder.setFooCord("foo");
|
||||
assertTrue(builder.hasFooCord());
|
||||
assertEquals(builder.getFooCord(), "foo");
|
||||
assertEquals("foo", builder.getFooCord());
|
||||
TestOneof2 message = builder.buildPartial();
|
||||
assertTrue(message.hasFooCord());
|
||||
assertEquals(message.getFooCord(), "foo");
|
||||
assertEquals("foo", message.getFooCord());
|
||||
assertEquals(message.getFooCordBytes(), TestUtil.toBytes("foo"));
|
||||
|
||||
assertFalse(builder.clearFooCord().hasFooCord());
|
||||
TestOneof2 message2 = builder.build();
|
||||
assertFalse(message2.hasFooCord());
|
||||
assertEquals(message2.getFooCord(), "");
|
||||
assertEquals("", message2.getFooCord());
|
||||
assertEquals(message2.getFooCordBytes(), TestUtil.toBytes(""));
|
||||
}
|
||||
|
||||
// StringPiece
|
||||
{
|
||||
TestOneof2.Builder builder = TestOneof2.newBuilder();
|
||||
assertEquals(builder.getFooStringPiece(), "");
|
||||
assertEquals("", builder.getFooStringPiece());
|
||||
builder.setFooStringPiece("foo");
|
||||
assertTrue(builder.hasFooStringPiece());
|
||||
assertEquals(builder.getFooStringPiece(), "foo");
|
||||
assertEquals("foo", builder.getFooStringPiece());
|
||||
TestOneof2 message = builder.buildPartial();
|
||||
assertTrue(message.hasFooStringPiece());
|
||||
assertEquals(message.getFooStringPiece(), "foo");
|
||||
assertEquals("foo", message.getFooStringPiece());
|
||||
assertEquals(message.getFooStringPieceBytes(), TestUtil.toBytes("foo"));
|
||||
|
||||
assertFalse(builder.clearFooStringPiece().hasFooStringPiece());
|
||||
TestOneof2 message2 = builder.build();
|
||||
assertFalse(message2.hasFooStringPiece());
|
||||
assertEquals(message2.getFooStringPiece(), "");
|
||||
assertEquals("", message2.getFooStringPiece());
|
||||
assertEquals(message2.getFooStringPieceBytes(), TestUtil.toBytes(""));
|
||||
}
|
||||
|
||||
@ -1410,20 +1404,20 @@ public class GeneratedMessageTest extends TestCase {
|
||||
{
|
||||
// set
|
||||
TestOneof2.Builder builder = TestOneof2.newBuilder();
|
||||
assertEquals(builder.getFooMessage().getQuxInt(), 0);
|
||||
assertEquals(0, builder.getFooMessage().getQuxInt());
|
||||
builder.setFooMessage(
|
||||
TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build());
|
||||
assertTrue(builder.hasFooMessage());
|
||||
assertEquals(builder.getFooMessage().getQuxInt(), 234);
|
||||
assertEquals(234, builder.getFooMessage().getQuxInt());
|
||||
TestOneof2 message = builder.buildPartial();
|
||||
assertTrue(message.hasFooMessage());
|
||||
assertEquals(message.getFooMessage().getQuxInt(), 234);
|
||||
assertEquals(234, message.getFooMessage().getQuxInt());
|
||||
|
||||
// clear
|
||||
assertFalse(builder.clearFooMessage().hasFooString());
|
||||
message = builder.build();
|
||||
assertFalse(message.hasFooMessage());
|
||||
assertEquals(message.getFooMessage().getQuxInt(), 0);
|
||||
assertEquals(0, message.getFooMessage().getQuxInt());
|
||||
|
||||
// nested builder
|
||||
builder = TestOneof2.newBuilder();
|
||||
@ -1432,10 +1426,10 @@ public class GeneratedMessageTest extends TestCase {
|
||||
assertFalse(builder.hasFooMessage());
|
||||
builder.getFooMessageBuilder().setQuxInt(123);
|
||||
assertTrue(builder.hasFooMessage());
|
||||
assertEquals(builder.getFooMessage().getQuxInt(), 123);
|
||||
assertEquals(123, builder.getFooMessage().getQuxInt());
|
||||
message = builder.build();
|
||||
assertTrue(message.hasFooMessage());
|
||||
assertEquals(message.getFooMessage().getQuxInt(), 123);
|
||||
assertEquals(123, message.getFooMessage().getQuxInt());
|
||||
}
|
||||
|
||||
// LazyMessage is tested in LazyMessageLiteTest.java
|
||||
@ -1448,7 +1442,7 @@ public class GeneratedMessageTest extends TestCase {
|
||||
TestOneof2 message = builder.setFooInt(123).build();
|
||||
TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
|
||||
assertTrue(message2.hasFooInt());
|
||||
assertEquals(message2.getFooInt(), 123);
|
||||
assertEquals(123, message2.getFooInt());
|
||||
}
|
||||
|
||||
// String
|
||||
@ -1457,7 +1451,7 @@ public class GeneratedMessageTest extends TestCase {
|
||||
TestOneof2 message = builder.setFooString("foo").build();
|
||||
TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
|
||||
assertTrue(message2.hasFooString());
|
||||
assertEquals(message2.getFooString(), "foo");
|
||||
assertEquals("foo", message2.getFooString());
|
||||
}
|
||||
|
||||
// Enum
|
||||
@ -1466,7 +1460,7 @@ public class GeneratedMessageTest extends TestCase {
|
||||
TestOneof2 message = builder.setFooEnum(TestOneof2.NestedEnum.BAR).build();
|
||||
TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
|
||||
assertTrue(message2.hasFooEnum());
|
||||
assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.BAR);
|
||||
assertEquals(TestOneof2.NestedEnum.BAR, message2.getFooEnum());
|
||||
}
|
||||
|
||||
// Message
|
||||
@ -1476,7 +1470,7 @@ public class GeneratedMessageTest extends TestCase {
|
||||
TestOneof2.NestedMessage.newBuilder().setQuxInt(234).build()).build();
|
||||
TestOneof2 message2 = TestOneof2.newBuilder().mergeFrom(message).build();
|
||||
assertTrue(message2.hasFooMessage());
|
||||
assertEquals(message2.getFooMessage().getQuxInt(), 234);
|
||||
assertEquals(234, message2.getFooMessage().getQuxInt());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1488,7 +1482,7 @@ public class GeneratedMessageTest extends TestCase {
|
||||
ByteString serialized = message.toByteString();
|
||||
TestOneof2 message2 = TestOneof2.parseFrom(serialized);
|
||||
assertTrue(message2.hasFooInt());
|
||||
assertEquals(message2.getFooInt(), 123);
|
||||
assertEquals(123, message2.getFooInt());
|
||||
}
|
||||
|
||||
// String
|
||||
@ -1498,7 +1492,7 @@ public class GeneratedMessageTest extends TestCase {
|
||||
ByteString serialized = message.toByteString();
|
||||
TestOneof2 message2 = TestOneof2.parseFrom(serialized);
|
||||
assertTrue(message2.hasFooString());
|
||||
assertEquals(message2.getFooString(), "foo");
|
||||
assertEquals("foo", message2.getFooString());
|
||||
}
|
||||
|
||||
// Enum
|
||||
@ -1508,7 +1502,7 @@ public class GeneratedMessageTest extends TestCase {
|
||||
ByteString serialized = message.toByteString();
|
||||
TestOneof2 message2 = TestOneof2.parseFrom(serialized);
|
||||
assertTrue(message2.hasFooEnum());
|
||||
assertEquals(message2.getFooEnum(), TestOneof2.NestedEnum.BAR);
|
||||
assertEquals(TestOneof2.NestedEnum.BAR, message2.getFooEnum());
|
||||
}
|
||||
|
||||
// Message
|
||||
@ -1519,7 +1513,7 @@ public class GeneratedMessageTest extends TestCase {
|
||||
ByteString serialized = message.toByteString();
|
||||
TestOneof2 message2 = TestOneof2.parseFrom(serialized);
|
||||
assertTrue(message2.hasFooMessage());
|
||||
assertEquals(message2.getFooMessage().getQuxInt(), 234);
|
||||
assertEquals(234, message2.getFooMessage().getQuxInt());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,6 +33,7 @@ package com.google.protobuf;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
|
||||
import com.google.protobuf.FieldPresenceTestProto.TestAllTypes;
|
||||
import com.google.protobuf.UnittestImportLite.ImportEnumLite;
|
||||
import com.google.protobuf.UnittestImportPublicLite.PublicImportMessageLite;
|
||||
import com.google.protobuf.UnittestLite.ForeignEnumLite;
|
||||
@ -52,7 +53,12 @@ import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime;
|
||||
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo;
|
||||
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals;
|
||||
import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -155,6 +161,31 @@ public class LiteTest extends TestCase {
|
||||
// expected.
|
||||
}
|
||||
}
|
||||
|
||||
public void testMemoization() throws Exception {
|
||||
TestAllExtensionsLite message = TestUtilLite.getAllLiteExtensionsSet();
|
||||
|
||||
// Test serialized size is memoized
|
||||
message.memoizedSerializedSize = -1;
|
||||
int size = message.getSerializedSize();
|
||||
assertTrue(size > 0);
|
||||
assertEquals(size, message.memoizedSerializedSize);
|
||||
|
||||
// Test hashCode is memoized
|
||||
assertEquals(0, message.memoizedHashCode);
|
||||
int hashCode = message.hashCode();
|
||||
assertTrue(hashCode != 0);
|
||||
assertEquals(hashCode, message.memoizedHashCode);
|
||||
|
||||
// Test isInitialized is memoized
|
||||
Field memo = message.getClass().getDeclaredField("memoizedIsInitialized");
|
||||
memo.setAccessible(true);
|
||||
memo.set(message, (byte) -1);
|
||||
boolean initialized = message.isInitialized();
|
||||
assertTrue(initialized);
|
||||
// We have to cast to Byte first. Casting to byte causes a type error
|
||||
assertEquals(1, ((Byte) memo.get(message)).intValue());
|
||||
}
|
||||
|
||||
public void testSanityCopyOnWrite() throws InvalidProtocolBufferException {
|
||||
// Since builders are implemented as a thin wrapper around a message
|
||||
@ -2378,4 +2409,187 @@ public class LiteTest extends TestCase {
|
||||
expected.getUnfinishedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we haven't screwed up the code generation for packing fields by default.
|
||||
public void testPackedSerialization() throws Exception {
|
||||
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
|
||||
builder.addRepeatedInt32(4321);
|
||||
builder.addRepeatedNestedEnum(TestAllTypes.NestedEnum.BAZ);
|
||||
TestAllTypes message = builder.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);
|
||||
}
|
||||
}
|
||||
|
||||
public void testAddAllIteratesOnce() {
|
||||
TestAllTypesLite message =
|
||||
TestAllTypesLite.newBuilder()
|
||||
.addAllRepeatedBool(new OneTimeIterableList(false))
|
||||
.addAllRepeatedInt32(new OneTimeIterableList(0))
|
||||
.addAllRepeatedInt64(new OneTimeIterableList(0L))
|
||||
.addAllRepeatedFloat(new OneTimeIterableList(0f))
|
||||
.addAllRepeatedDouble(new OneTimeIterableList(0d))
|
||||
.addAllRepeatedBytes(new OneTimeIterableList(ByteString.EMPTY))
|
||||
.addAllRepeatedString(new OneTimeIterableList(""))
|
||||
.addAllRepeatedNestedMessage(
|
||||
new OneTimeIterableList(NestedMessage.getDefaultInstance()))
|
||||
.addAllRepeatedBool(new OneTimeIterable(false))
|
||||
.addAllRepeatedInt32(new OneTimeIterable(0))
|
||||
.addAllRepeatedInt64(new OneTimeIterable(0L))
|
||||
.addAllRepeatedFloat(new OneTimeIterable(0f))
|
||||
.addAllRepeatedDouble(new OneTimeIterable(0d))
|
||||
.addAllRepeatedBytes(new OneTimeIterable(ByteString.EMPTY))
|
||||
.addAllRepeatedString(new OneTimeIterable(""))
|
||||
.addAllRepeatedNestedMessage(new OneTimeIterable(NestedMessage.getDefaultInstance()))
|
||||
.build();
|
||||
}
|
||||
|
||||
public void testAddAllIteratesOnce_throwsOnNull() {
|
||||
TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder();
|
||||
try {
|
||||
builder.addAllRepeatedBool(new OneTimeIterableList(true, false, (Boolean) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 2 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedBoolCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder.addAllRepeatedBool(new OneTimeIterable(true, false, (Boolean) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 2 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedBoolCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedBool(new OneTimeIterableList((Boolean) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 0 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedBoolCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedInt32(new OneTimeIterableList((Integer) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 0 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedInt32Count());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedInt64(new OneTimeIterableList((Long) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 0 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedInt64Count());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedFloat(new OneTimeIterableList((Float) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 0 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedFloatCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedDouble(new OneTimeIterableList((Double) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 0 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedDoubleCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedBytes(new OneTimeIterableList((ByteString) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 0 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedBytesCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedString(new OneTimeIterableList("", "", (String) null, ""));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 2 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedStringCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedString(new OneTimeIterable("", "", (String) null, ""));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 2 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedStringCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedString(new OneTimeIterableList((String) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 0 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedStringCount());
|
||||
}
|
||||
|
||||
try {
|
||||
builder = TestAllTypesLite.newBuilder();
|
||||
builder.addAllRepeatedNestedMessage(new OneTimeIterableList((NestedMessage) null));
|
||||
fail();
|
||||
} catch (NullPointerException expected) {
|
||||
assertEquals("Element at index 0 is null.", expected.getMessage());
|
||||
assertEquals(0, builder.getRepeatedNestedMessageCount());
|
||||
}
|
||||
}
|
||||
|
||||
private static final class OneTimeIterableList<T> extends ArrayList<T> {
|
||||
private boolean wasIterated = false;
|
||||
|
||||
OneTimeIterableList(T... contents) {
|
||||
addAll(Arrays.asList(contents));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
if (wasIterated) {
|
||||
fail();
|
||||
}
|
||||
wasIterated = true;
|
||||
return super.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
private static final class OneTimeIterable<T> implements Iterable<T> {
|
||||
private final List<T> list;
|
||||
private boolean wasIterated = false;
|
||||
|
||||
OneTimeIterable(T... contents) {
|
||||
list = Arrays.asList(contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
if (wasIterated) {
|
||||
fail();
|
||||
}
|
||||
wasIterated = true;
|
||||
return list.iterator();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -408,12 +408,12 @@ public final class MapForProto2LiteTest extends TestCase {
|
||||
TestMap map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToInt32Field(5, bytes)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0);
|
||||
assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1));
|
||||
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToStringField(stringKey, 5)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToStringFieldOrDefault(0, null), "");
|
||||
assertEquals("", map.getInt32ToStringFieldOrDefault(0, null));
|
||||
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToBytesField(stringKey, 5)
|
||||
@ -423,7 +423,7 @@ public final class MapForProto2LiteTest extends TestCase {
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToEnumField(stringKey, bytes)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO);
|
||||
assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null));
|
||||
|
||||
try {
|
||||
tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
@ -439,7 +439,7 @@ public final class MapForProto2LiteTest extends TestCase {
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putStringToInt32Field(stringKey, bytes)
|
||||
.build());
|
||||
assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0);
|
||||
assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1));
|
||||
}
|
||||
|
||||
public void testMergeFrom() throws Exception {
|
||||
|
@ -546,12 +546,12 @@ public class MapForProto2Test extends TestCase {
|
||||
TestMap map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToInt32Field(5, bytes)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0);
|
||||
assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1));
|
||||
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToStringField(stringKey, 5)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToStringFieldOrDefault(0, null), "");
|
||||
assertEquals("", map.getInt32ToStringFieldOrDefault(0, null));
|
||||
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToBytesField(stringKey, 5)
|
||||
@ -561,7 +561,7 @@ public class MapForProto2Test extends TestCase {
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToEnumField(stringKey, bytes)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO);
|
||||
assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null));
|
||||
|
||||
try {
|
||||
tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
@ -577,7 +577,7 @@ public class MapForProto2Test extends TestCase {
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putStringToInt32Field(stringKey, bytes)
|
||||
.build());
|
||||
assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0);
|
||||
assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1));
|
||||
}
|
||||
|
||||
public void testMergeFrom() throws Exception {
|
||||
|
@ -576,12 +576,12 @@ public class MapTest extends TestCase {
|
||||
TestMap map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToInt32Field(5, bytes)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToInt32FieldOrDefault(5, -1), 0);
|
||||
assertEquals(0, map.getInt32ToInt32FieldOrDefault(5, -1));
|
||||
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToStringField(stringKey, 5)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToStringFieldOrDefault(0, null), "");
|
||||
assertEquals("", map.getInt32ToStringFieldOrDefault(0, null));
|
||||
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToBytesField(stringKey, 5)
|
||||
@ -591,7 +591,7 @@ public class MapTest extends TestCase {
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putInt32ToEnumField(stringKey, bytes)
|
||||
.build());
|
||||
assertEquals(map.getInt32ToEnumFieldOrDefault(0, null), TestMap.EnumValue.FOO);
|
||||
assertEquals(TestMap.EnumValue.FOO, map.getInt32ToEnumFieldOrDefault(0, null));
|
||||
|
||||
try {
|
||||
tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
@ -607,7 +607,7 @@ public class MapTest extends TestCase {
|
||||
map = tryParseTestMap(BizarroTestMap.newBuilder()
|
||||
.putStringToInt32Field(stringKey, bytes)
|
||||
.build());
|
||||
assertEquals(map.getStringToInt32FieldOrDefault(stringKey, -1), 0);
|
||||
assertEquals(0, map.getStringToInt32FieldOrDefault(stringKey, -1));
|
||||
}
|
||||
|
||||
public void testMergeFrom() throws Exception {
|
||||
|
@ -321,8 +321,10 @@ public class MessageTest extends TestCase {
|
||||
|
||||
assertTrue(result.getField(result.getDescriptorForType()
|
||||
.findFieldByName("repeated_foreign_message")) instanceof List<?>);
|
||||
assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
|
||||
.findFieldByName("repeated_foreign_message")), 0);
|
||||
assertEquals(
|
||||
0,
|
||||
result.getRepeatedFieldCount(
|
||||
result.getDescriptorForType().findFieldByName("repeated_foreign_message")));
|
||||
}
|
||||
|
||||
/** Test reading repeated message from DynamicMessage. */
|
||||
@ -345,7 +347,9 @@ public class MessageTest extends TestCase {
|
||||
|
||||
assertTrue(result.getField(result.getDescriptorForType()
|
||||
.findFieldByName("repeated_foreign_message")) instanceof List<?>);
|
||||
assertEquals(result.getRepeatedFieldCount(result.getDescriptorForType()
|
||||
.findFieldByName("repeated_foreign_message")), 2);
|
||||
assertEquals(
|
||||
2,
|
||||
result.getRepeatedFieldCount(
|
||||
result.getDescriptorForType().findFieldByName("repeated_foreign_message")));
|
||||
}
|
||||
}
|
||||
|
@ -92,5 +92,31 @@ public class TestBadIdentifiers extends TestCase {
|
||||
assertEquals(0L, message.getExtension(
|
||||
TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldList).longValue());
|
||||
|
||||
assertEquals("", message.getFieldName32());
|
||||
assertEquals("", message.getFieldName33());
|
||||
assertEquals(0, message.get2Conflict34());
|
||||
assertEquals(0, message.get2Conflict35());
|
||||
|
||||
}
|
||||
|
||||
public void testNumberFields() throws Exception {
|
||||
TestBadIdentifiersProto.TestLeadingNumberFields message =
|
||||
TestBadIdentifiersProto.TestLeadingNumberFields.getDefaultInstance();
|
||||
// Make sure generated accessors are properly named.
|
||||
assertFalse(message.has30DayImpressions());
|
||||
assertEquals(0, message.get30DayImpressions());
|
||||
assertEquals(0, message.get60DayImpressionsCount());
|
||||
assertEquals(0, message.get60DayImpressionsList().size());
|
||||
|
||||
assertFalse(message.has2Underscores());
|
||||
assertEquals("", message.get2Underscores());
|
||||
assertEquals(0, message.get2RepeatedUnderscoresCount());
|
||||
assertEquals(0, message.get2RepeatedUnderscoresList().size());
|
||||
|
||||
assertFalse(message.has32());
|
||||
assertEquals(0, message.get32());
|
||||
assertEquals(0, message.get64Count());
|
||||
assertEquals(0, message.get64List().size());
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* Tests that proto2 api generation doesn't cause compile errors when compiling protocol buffers
|
||||
* that have names that would otherwise conflict if not fully qualified (like @Deprecated
|
||||
* and @Override).
|
||||
*
|
||||
* <p>Forked from {@link TestBadIdentifiers}.
|
||||
*
|
||||
* @author jonp@google.com (Jon Perlow)
|
||||
*/
|
||||
public final class TestBadIdentifiersLite extends TestCase {
|
||||
|
||||
public void testCompilation() {
|
||||
// If this compiles, it means the generation was correct.
|
||||
TestBadIdentifiersProto.Deprecated.newBuilder();
|
||||
TestBadIdentifiersProto.Override.newBuilder();
|
||||
}
|
||||
|
||||
public void testConflictingFieldNames() throws Exception {
|
||||
TestBadIdentifiersProto.TestConflictingFieldNames message =
|
||||
TestBadIdentifiersProto.TestConflictingFieldNames.getDefaultInstance();
|
||||
// Make sure generated accessors are properly named.
|
||||
assertEquals(0, message.getInt32Field1Count());
|
||||
assertEquals(0, message.getEnumField2Count());
|
||||
assertEquals(0, message.getStringField3Count());
|
||||
assertEquals(0, message.getBytesField4Count());
|
||||
assertEquals(0, message.getMessageField5Count());
|
||||
|
||||
assertEquals(0, message.getInt32FieldCount11());
|
||||
assertEquals(0, message.getEnumFieldCount12().getNumber());
|
||||
assertEquals("", message.getStringFieldCount13());
|
||||
assertEquals(ByteString.EMPTY, message.getBytesFieldCount14());
|
||||
assertEquals(0, message.getMessageFieldCount15().getSerializedSize());
|
||||
|
||||
assertEquals(0, message.getInt32Field21Count());
|
||||
assertEquals(0, message.getEnumField22Count());
|
||||
assertEquals(0, message.getStringField23Count());
|
||||
assertEquals(0, message.getBytesField24Count());
|
||||
assertEquals(0, message.getMessageField25Count());
|
||||
|
||||
assertEquals(0, message.getInt32Field1List().size());
|
||||
assertEquals(0, message.getInt32FieldList31());
|
||||
|
||||
assertEquals(0, message.getInt64FieldCount());
|
||||
assertEquals(0L, message.getExtension(
|
||||
TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldCount).longValue());
|
||||
assertEquals(0L, message.getExtension(
|
||||
TestBadIdentifiersProto.TestConflictingFieldNames.int64FieldList).longValue());
|
||||
}
|
||||
}
|
@ -30,8 +30,6 @@
|
||||
|
||||
package com.google.protobuf;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.protobuf.Descriptors.Descriptor;
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor;
|
||||
import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy;
|
||||
@ -1079,12 +1077,12 @@ public class TextFormatTest extends TestCase {
|
||||
{
|
||||
TestMap.Builder dest = TestMap.newBuilder();
|
||||
TextFormat.merge(text, dest);
|
||||
assertThat(dest.build()).isEqualTo(message);
|
||||
assertEquals(message, dest.build());
|
||||
}
|
||||
{
|
||||
TestMap.Builder dest = TestMap.newBuilder();
|
||||
parserWithOverwriteForbidden.merge(text, dest);
|
||||
assertThat(dest.build()).isEqualTo(message);
|
||||
assertEquals(message, dest.build());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1096,10 +1094,10 @@ public class TextFormatTest extends TestCase {
|
||||
TestMap.Builder dest = TestMap.newBuilder();
|
||||
parserWithOverwriteForbidden.merge(text, dest);
|
||||
TestMap message = dest.build();
|
||||
assertThat(message.getStringToInt32Field().size()).isEqualTo(2);
|
||||
assertThat(message.getInt32ToMessageField().size()).isEqualTo(2);
|
||||
assertThat(message.getStringToInt32Field().get("x")).isEqualTo(10);
|
||||
assertThat(message.getInt32ToMessageField().get(2).getValue()).isEqualTo(200);
|
||||
assertEquals(2, message.getStringToInt32Field().size());
|
||||
assertEquals(2, message.getInt32ToMessageField().size());
|
||||
assertEquals(10, message.getStringToInt32Field().get("x").intValue());
|
||||
assertEquals(200, message.getInt32ToMessageField().get(2).getValue());
|
||||
}
|
||||
|
||||
public void testMapShortFormEmpty() throws Exception {
|
||||
@ -1108,8 +1106,8 @@ public class TextFormatTest extends TestCase {
|
||||
TestMap.Builder dest = TestMap.newBuilder();
|
||||
parserWithOverwriteForbidden.merge(text, dest);
|
||||
TestMap message = dest.build();
|
||||
assertThat(message.getStringToInt32Field().size()).isEqualTo(0);
|
||||
assertThat(message.getInt32ToMessageField().size()).isEqualTo(0);
|
||||
assertEquals(0, message.getStringToInt32Field().size());
|
||||
assertEquals(0, message.getInt32ToMessageField().size());
|
||||
}
|
||||
|
||||
public void testMapShortFormTrailingComma() throws Exception {
|
||||
@ -1119,7 +1117,7 @@ public class TextFormatTest extends TestCase {
|
||||
parserWithOverwriteForbidden.merge(text, dest);
|
||||
fail("Expected parse exception.");
|
||||
} catch (TextFormat.ParseException e) {
|
||||
assertThat(e).hasMessageThat().isEqualTo("1:48: Expected \"{\".");
|
||||
assertEquals("1:48: Expected \"{\".", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1134,8 +1132,8 @@ public class TextFormatTest extends TestCase {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
defaultParser.merge(text, builder);
|
||||
TestMap map = builder.build();
|
||||
assertThat(map.getInt32ToInt32Field().size()).isEqualTo(2);
|
||||
assertThat(map.getInt32ToInt32Field().get(1).intValue()).isEqualTo(30);
|
||||
assertEquals(2, map.getInt32ToInt32Field().size());
|
||||
assertEquals(30, map.getInt32ToInt32Field().get(1).intValue());
|
||||
}
|
||||
|
||||
{
|
||||
@ -1144,8 +1142,8 @@ public class TextFormatTest extends TestCase {
|
||||
TestMap.Builder builder = TestMap.newBuilder();
|
||||
defaultParser.merge(text, builder);
|
||||
TestMap map = builder.build();
|
||||
assertThat(map.getInt32ToInt32Field().size()).isEqualTo(2);
|
||||
assertThat(map.getInt32ToInt32Field().get(1).intValue()).isEqualTo(30);
|
||||
assertEquals(2, map.getInt32ToInt32Field().size());
|
||||
assertEquals(30, map.getInt32ToInt32Field().get(1).intValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor;
|
||||
import com.google.protobuf.Descriptors.FieldDescriptor;
|
||||
import com.google.protobuf.FieldPresenceTestProto.TestAllTypes;
|
||||
import com.google.protobuf.TextFormat.ParseException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
@ -151,18 +150,15 @@ public class UnknownEnumValueTest extends TestCase {
|
||||
assertEquals(4321, unknown4321.getNumber());
|
||||
assertEquals(5432, unknown5432.getNumber());
|
||||
assertEquals(6543, unknown6543.getNumber());
|
||||
|
||||
|
||||
// Unknown EnumValueDescriptor will map to UNRECOGNIZED.
|
||||
assertEquals(
|
||||
TestAllTypes.NestedEnum.valueOf(unknown4321),
|
||||
TestAllTypes.NestedEnum.UNRECOGNIZED);
|
||||
TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown4321));
|
||||
assertEquals(
|
||||
TestAllTypes.NestedEnum.valueOf(unknown5432),
|
||||
TestAllTypes.NestedEnum.UNRECOGNIZED);
|
||||
TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown5432));
|
||||
assertEquals(
|
||||
TestAllTypes.NestedEnum.valueOf(unknown6543),
|
||||
TestAllTypes.NestedEnum.UNRECOGNIZED);
|
||||
|
||||
TestAllTypes.NestedEnum.UNRECOGNIZED, TestAllTypes.NestedEnum.valueOf(unknown6543));
|
||||
|
||||
// Setters also accept unknown EnumValueDescriptor.
|
||||
builder.setField(optionalNestedEnumField, unknown6543);
|
||||
builder.setRepeatedField(repeatedNestedEnumField, 0, unknown4321);
|
||||
|
@ -148,6 +148,12 @@ message TestConflictingFieldNames {
|
||||
// the method getInt32FieldList().
|
||||
required int32 int32_field_list = 31; // NO_PROTO3
|
||||
|
||||
// These field pairs have the same Java converted name
|
||||
optional string field_name = 32; // NO_PROTO3
|
||||
optional string field__name = 33; // NO_PROTO3
|
||||
optional int32 _2conflict = 34; // NO_PROTO3
|
||||
optional int32 __2conflict = 35;
|
||||
|
||||
extensions 1000 to max; // NO_PROTO3
|
||||
|
||||
repeated int64 int64_field = 41;
|
||||
@ -166,3 +172,14 @@ message TestMapField {
|
||||
|
||||
map<int32, int32> map_field = 1;
|
||||
}
|
||||
|
||||
message TestLeadingNumberFields {
|
||||
optional int32 _30day_impressions = 1;
|
||||
repeated string _60day_impressions = 2;
|
||||
|
||||
optional string __2_underscores = 3;
|
||||
repeated string __2repeated_underscores = 4;
|
||||
|
||||
optional int32 _32 = 32;
|
||||
repeated int64 _64 = 64;
|
||||
}
|
||||
|
@ -83,6 +83,17 @@ public final class Durations {
|
||||
return COMPARATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two durations. The value returned is identical to what would be returned by:
|
||||
* {@code Durations.comparator().compare(x, y)}.
|
||||
*
|
||||
* @return the value {@code 0} if {@code x == y}; a value less than {@code 0} if {@code x < y};
|
||||
* and a value greater than {@code 0} if {@code x > y}
|
||||
*/
|
||||
public static int compare(Duration x, Duration y) {
|
||||
return COMPARATOR.compare(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given {@link Duration} is valid. The {@code seconds} value must be in the
|
||||
* range [-315,576,000,000, +315,576,000,000]. The {@code nanos} value must be in the range
|
||||
|
@ -311,16 +311,19 @@ public class FieldMaskUtil {
|
||||
return replacePrimitiveFields;
|
||||
}
|
||||
|
||||
public void setReplaceMessageFields(boolean value) {
|
||||
public MergeOptions setReplaceMessageFields(boolean value) {
|
||||
replaceMessageFields = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setReplaceRepeatedFields(boolean value) {
|
||||
public MergeOptions setReplaceRepeatedFields(boolean value) {
|
||||
replaceRepeatedFields = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setReplacePrimitiveFields(boolean value) {
|
||||
public MergeOptions setReplacePrimitiveFields(boolean value) {
|
||||
replacePrimitiveFields = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1686,7 +1686,11 @@ public class JsonFormat {
|
||||
}
|
||||
|
||||
private ByteString parseBytes(JsonElement json) throws InvalidProtocolBufferException {
|
||||
return ByteString.copyFrom(BaseEncoding.base64().decode(json.getAsString()));
|
||||
try {
|
||||
return ByteString.copyFrom(BaseEncoding.base64().decode(json.getAsString()));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return ByteString.copyFrom(BaseEncoding.base64Url().decode(json.getAsString()));
|
||||
}
|
||||
}
|
||||
|
||||
private EnumValueDescriptor parseEnum(EnumDescriptor enumDescriptor, JsonElement json)
|
||||
|
@ -114,6 +114,17 @@ public final class Timestamps {
|
||||
return COMPARATOR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two timestamps. The value returned is identical to what would be returned by:
|
||||
* {@code Timestamps.comparator().compare(x, y)}.
|
||||
*
|
||||
* @return the value {@code 0} if {@code x == y}; a value less than {@code 0} if {@code x < y};
|
||||
* and a value greater than {@code 0} if {@code x > y}
|
||||
*/
|
||||
public static int compare(Timestamp x, Timestamp y) {
|
||||
return COMPARATOR.compare(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given {@link Timestamp} is valid. The {@code seconds} value must be in the
|
||||
* range [-62,135,596,800, +253,402,300,799] (i.e., between 0001-01-01T00:00:00Z and
|
||||
|
@ -73,7 +73,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
@ -1144,7 +1143,8 @@ public class JsonFormatTest extends TestCase {
|
||||
}
|
||||
|
||||
public void testParserAcceptBase64Variants() throws Exception {
|
||||
assertAccepts("optionalBytes", "AQI");
|
||||
assertAccepts("optionalBytes", "AQI"); // No padding
|
||||
assertAccepts("optionalBytes", "-_w"); // base64Url, no padding
|
||||
}
|
||||
|
||||
public void testParserRejectInvalidEnumValue() throws Exception {
|
||||
|
@ -390,11 +390,13 @@ jspb.BinaryEncoder.prototype.writeDouble = function(value) {
|
||||
|
||||
|
||||
/**
|
||||
* Writes a boolean value to the buffer as a varint.
|
||||
* @param {boolean} value The value to write.
|
||||
* Writes a boolean value to the buffer as a varint. We allow numbers as input
|
||||
* because the JSPB code generator uses 0/1 instead of true/false to save space
|
||||
* in the string representation of the proto.
|
||||
* @param {boolean|number} value The value to write.
|
||||
*/
|
||||
jspb.BinaryEncoder.prototype.writeBool = function(value) {
|
||||
goog.asserts.assert(goog.isBoolean(value));
|
||||
goog.asserts.assert(goog.isBoolean(value) || goog.isNumber(value));
|
||||
this.buffer_.push(value ? 1 : 0);
|
||||
};
|
||||
|
||||
|
@ -970,10 +970,6 @@ jspb.utils.byteSourceToUint8Array = function(data) {
|
||||
return /** @type {!Uint8Array} */(new Uint8Array(data));
|
||||
}
|
||||
|
||||
if (data.constructor === Buffer) {
|
||||
return /** @type {!Uint8Array} */(new Uint8Array(data));
|
||||
}
|
||||
|
||||
if (data.constructor === Array) {
|
||||
data = /** @type {!Array.<number>} */(data);
|
||||
return /** @type {!Uint8Array} */(new Uint8Array(data));
|
||||
|
@ -235,7 +235,7 @@ jspb.BinaryWriter.prototype.getResultBuffer = function() {
|
||||
|
||||
|
||||
/**
|
||||
* Converts the encoded data into a bas64-encoded string.
|
||||
* Converts the encoded data into a base64-encoded string.
|
||||
* @return {string}
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.getResultBase64String = function() {
|
||||
@ -716,13 +716,15 @@ jspb.BinaryWriter.prototype.writeDouble = function(field, value) {
|
||||
|
||||
|
||||
/**
|
||||
* Writes a boolean field to the buffer.
|
||||
* Writes a boolean field to the buffer. We allow numbers as input
|
||||
* because the JSPB code generator uses 0/1 instead of true/false to save space
|
||||
* in the string representation of the proto.
|
||||
* @param {number} field The field number.
|
||||
* @param {boolean?} value The value to write.
|
||||
* @param {boolean?|number?} value The value to write.
|
||||
*/
|
||||
jspb.BinaryWriter.prototype.writeBool = function(field, value) {
|
||||
if (value == null) return;
|
||||
goog.asserts.assert(goog.isBoolean(value));
|
||||
goog.asserts.assert(goog.isBoolean(value) || goog.isNumber(value));
|
||||
this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
|
||||
this.encoder_.writeBool(value);
|
||||
};
|
||||
|
355
js/compatibility_tests/v3.1.0/binary/arith_test.js
Normal file
355
js/compatibility_tests/v3.1.0/binary/arith_test.js
Normal file
@ -0,0 +1,355 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/**
|
||||
* @fileoverview Test cases for Int64-manipulation functions.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author cfallin@google.com (Chris Fallin)
|
||||
*/
|
||||
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.arith.Int64');
|
||||
goog.require('jspb.arith.UInt64');
|
||||
|
||||
|
||||
describe('binaryArithTest', function() {
|
||||
/**
|
||||
* Tests comparison operations.
|
||||
*/
|
||||
it('testCompare', function() {
|
||||
var a = new jspb.arith.UInt64(1234, 5678);
|
||||
var b = new jspb.arith.UInt64(1234, 5678);
|
||||
assertEquals(a.cmp(b), 0);
|
||||
assertEquals(b.cmp(a), 0);
|
||||
b.lo -= 1;
|
||||
assertEquals(a.cmp(b), 1);
|
||||
assertEquals(b.cmp(a), -1);
|
||||
b.lo += 2;
|
||||
assertEquals(a.cmp(b), -1);
|
||||
assertEquals(b.cmp(a), 1);
|
||||
b.lo = a.lo;
|
||||
b.hi = a.hi - 1;
|
||||
assertEquals(a.cmp(b), 1);
|
||||
assertEquals(b.cmp(a), -1);
|
||||
|
||||
assertEquals(a.zero(), false);
|
||||
assertEquals(a.msb(), false);
|
||||
assertEquals(a.lsb(), false);
|
||||
a.hi = 0;
|
||||
a.lo = 0;
|
||||
assertEquals(a.zero(), true);
|
||||
a.hi = 0x80000000;
|
||||
assertEquals(a.zero(), false);
|
||||
assertEquals(a.msb(), true);
|
||||
a.lo = 0x00000001;
|
||||
assertEquals(a.lsb(), true);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests shifts.
|
||||
*/
|
||||
it('testShifts', function() {
|
||||
var a = new jspb.arith.UInt64(1, 0);
|
||||
assertEquals(a.lo, 1);
|
||||
assertEquals(a.hi, 0);
|
||||
var orig = a;
|
||||
a = a.leftShift();
|
||||
assertEquals(orig.lo, 1); // original unmodified.
|
||||
assertEquals(orig.hi, 0);
|
||||
assertEquals(a.lo, 2);
|
||||
assertEquals(a.hi, 0);
|
||||
a = a.leftShift();
|
||||
assertEquals(a.lo, 4);
|
||||
assertEquals(a.hi, 0);
|
||||
for (var i = 0; i < 29; i++) {
|
||||
a = a.leftShift();
|
||||
}
|
||||
assertEquals(a.lo, 0x80000000);
|
||||
assertEquals(a.hi, 0);
|
||||
a = a.leftShift();
|
||||
assertEquals(a.lo, 0);
|
||||
assertEquals(a.hi, 1);
|
||||
a = a.leftShift();
|
||||
assertEquals(a.lo, 0);
|
||||
assertEquals(a.hi, 2);
|
||||
a = a.rightShift();
|
||||
a = a.rightShift();
|
||||
assertEquals(a.lo, 0x80000000);
|
||||
assertEquals(a.hi, 0);
|
||||
a = a.rightShift();
|
||||
assertEquals(a.lo, 0x40000000);
|
||||
assertEquals(a.hi, 0);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests additions.
|
||||
*/
|
||||
it('testAdd', function() {
|
||||
var a = new jspb.arith.UInt64(/* lo = */ 0x89abcdef,
|
||||
/* hi = */ 0x01234567);
|
||||
var b = new jspb.arith.UInt64(/* lo = */ 0xff52ab91,
|
||||
/* hi = */ 0x92fa2123);
|
||||
// Addition with carry.
|
||||
var c = a.add(b);
|
||||
assertEquals(a.lo, 0x89abcdef); // originals unmodified.
|
||||
assertEquals(a.hi, 0x01234567);
|
||||
assertEquals(b.lo, 0xff52ab91);
|
||||
assertEquals(b.hi, 0x92fa2123);
|
||||
assertEquals(c.lo, 0x88fe7980);
|
||||
assertEquals(c.hi, 0x941d668b);
|
||||
|
||||
// Simple addition without carry.
|
||||
a.lo = 2;
|
||||
a.hi = 0;
|
||||
b.lo = 3;
|
||||
b.hi = 0;
|
||||
c = a.add(b);
|
||||
assertEquals(c.lo, 5);
|
||||
assertEquals(c.hi, 0);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Test subtractions.
|
||||
*/
|
||||
it('testSub', function() {
|
||||
var kLength = 10;
|
||||
var hiValues = [0x1682ef32,
|
||||
0x583902f7,
|
||||
0xb62f5955,
|
||||
0x6ea99bbf,
|
||||
0x25a39c20,
|
||||
0x0700a08b,
|
||||
0x00f7304d,
|
||||
0x91a5b5af,
|
||||
0x89077fd2,
|
||||
0xe09e347c];
|
||||
var loValues = [0xe1538b18,
|
||||
0xbeacd556,
|
||||
0x74100758,
|
||||
0x96e3cb26,
|
||||
0x56c37c3f,
|
||||
0xe00b3f7d,
|
||||
0x859f25d7,
|
||||
0xc2ee614a,
|
||||
0xe1d21cd7,
|
||||
0x30aae6a4];
|
||||
for (var i = 0; i < kLength; i++) {
|
||||
for (var j = 0; j < kLength; j++) {
|
||||
var a = new jspb.arith.UInt64(loValues[i], hiValues[j]);
|
||||
var b = new jspb.arith.UInt64(loValues[j], hiValues[i]);
|
||||
var c = a.add(b).sub(b);
|
||||
assertEquals(c.hi, a.hi);
|
||||
assertEquals(c.lo, a.lo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests 32-by-32 multiplication.
|
||||
*/
|
||||
it('testMul32x32', function() {
|
||||
var testData = [
|
||||
// a b low(a*b) high(a*b)
|
||||
[0xc0abe2f8, 0x1607898a, 0x5de711b0, 0x109471b8],
|
||||
[0x915eb3cb, 0x4fb66d0e, 0xbd0d441a, 0x2d43d0bc],
|
||||
[0xfe4efe70, 0x80b48c37, 0xbcddea10, 0x7fdada0c],
|
||||
[0xe222fd4a, 0xe43d524a, 0xd5e0eb64, 0xc99d549c],
|
||||
[0xd171f469, 0xb94ebd01, 0x4be17969, 0x979bc4fa],
|
||||
[0x829cc1df, 0xe2598b38, 0xf4157dc8, 0x737c12ad],
|
||||
[0xf10c3767, 0x8382881e, 0x942b3612, 0x7bd428b8],
|
||||
[0xb0f6dd24, 0x232597e1, 0x079c98a4, 0x184bbce7],
|
||||
[0xfcdb05a7, 0x902f55bc, 0x636199a4, 0x8e69f412],
|
||||
[0x0dd0bfa9, 0x916e27b1, 0x6e2542d9, 0x07d92e65]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testData.length; i++) {
|
||||
var a = testData[i][0] >>> 0;
|
||||
var b = testData[i][1] >>> 0;
|
||||
var cLow = testData[i][2] >>> 0;
|
||||
var cHigh = testData[i][3] >>> 0;
|
||||
var c = jspb.arith.UInt64.mul32x32(a, b);
|
||||
assertEquals(c.lo, cLow);
|
||||
assertEquals(c.hi, cHigh);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests 64-by-32 multiplication.
|
||||
*/
|
||||
it('testMul', function() {
|
||||
// 64x32 bits produces 96 bits of product. The multiplication function under
|
||||
// test truncates the top 32 bits, so we compare against a 64-bit expected
|
||||
// product.
|
||||
var testData = [
|
||||
// low(a) high(a) low(a*b) high(a*b)
|
||||
[0xec10955b, 0x360eb168, 0x4b7f3f5b, 0xbfcb7c59, 0x9517da5f],
|
||||
[0x42b000fc, 0x9d101642, 0x6fa1ab72, 0x2584c438, 0x6a9e6d2b],
|
||||
[0xf42d4fb4, 0xae366403, 0xa65a1000, 0x92434000, 0x1ff978df],
|
||||
[0x17e2f56b, 0x25487693, 0xf13f98c7, 0x73794e2d, 0xa96b0c6a],
|
||||
[0x492f241f, 0x76c0eb67, 0x7377ac44, 0xd4336c3c, 0xfc4b1ebe],
|
||||
[0xd6b92321, 0xe184fa48, 0xd6e76904, 0x93141584, 0xcbf44da1],
|
||||
[0x4bf007ea, 0x968c0a9e, 0xf5e4026a, 0x4fdb1ae4, 0x61b9fb7d],
|
||||
[0x10a83be7, 0x2d685ba6, 0xc9e5fb7f, 0x2ad43499, 0x3742473d],
|
||||
[0x2f261829, 0x1aca681a, 0x3d3494e3, 0x8213205b, 0x283719f8],
|
||||
[0xe4f2ce21, 0x2e74b7bd, 0xd801b38b, 0xbc17feeb, 0xc6c44e0f]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testData.length; i++) {
|
||||
var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
|
||||
var prod = a.mul(testData[i][2]);
|
||||
assertEquals(prod.lo, testData[i][3]);
|
||||
assertEquals(prod.hi, testData[i][4]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests 64-div-by-32 division.
|
||||
*/
|
||||
it('testDiv', function() {
|
||||
// Compute a/b, yielding quot = a/b and rem = a%b.
|
||||
var testData = [
|
||||
// --- divisors in (0, 2^32-1) to test full divisor range
|
||||
// low(a) high(a) b low(quot) high(quot) rem
|
||||
[0x712443f1, 0xe85cefcc, 0xc1a7050b, 0x332c79ad, 0x00000001, 0x92ffa882],
|
||||
[0x11912915, 0xb2699eb5, 0x30467cbe, 0xb21b4be4, 0x00000003, 0x283465dd],
|
||||
[0x0d917982, 0x201f2a6e, 0x3f35bf03, 0x8217c8e4, 0x00000000, 0x153402d6],
|
||||
[0xa072c108, 0x74020c96, 0xc60568fd, 0x95f9613e, 0x00000000, 0x3f4676c2],
|
||||
[0xd845d5d8, 0xcdd235c4, 0x20426475, 0x6154e78b, 0x00000006, 0x202fb751],
|
||||
[0xa4dbf71f, 0x9e90465e, 0xf08e022f, 0xa8be947f, 0x00000000, 0xbe43b5ce],
|
||||
[0x3dbe627f, 0xa791f4b9, 0x28a5bd89, 0x1f5dfe93, 0x00000004, 0x02bf9ed4],
|
||||
[0x5c1c53ee, 0xccf5102e, 0x198576e7, 0x07e3ae31, 0x00000008, 0x02ea8fb7],
|
||||
[0xfef1e581, 0x04714067, 0xca6540c1, 0x059e73ec, 0x00000000, 0x31658095],
|
||||
[0x1e2dd90c, 0x13dd6667, 0x8b2184c3, 0x248d1a42, 0x00000000, 0x4ca6d0c6],
|
||||
// --- divisors in (0, 2^16-1) to test larger quotient high-words
|
||||
// low(a) high(a) b low(quot) high(quot) rem
|
||||
[0x86722b47, 0x2cd57c9a, 0x00003123, 0x2ae41b7a, 0x0000e995, 0x00000f99],
|
||||
[0x1dd7884c, 0xf5e839bc, 0x00009eeb, 0x5c886242, 0x00018c21, 0x000099b6],
|
||||
[0x5c53d625, 0x899fc7e5, 0x000087d7, 0xd625007a, 0x0001035c, 0x000019af],
|
||||
[0x6932d932, 0x9d0a5488, 0x000051fb, 0x9d976143, 0x0001ea63, 0x00004981],
|
||||
[0x4d18bb85, 0x0c92fb31, 0x00001d9f, 0x03265ab4, 0x00006cac, 0x000001b9],
|
||||
[0xbe756768, 0xdea67ccb, 0x00008a03, 0x58add442, 0x00019cff, 0x000056a2],
|
||||
[0xe2466f9a, 0x2521f114, 0x0000c350, 0xa0c0860d, 0x000030ab, 0x0000a48a],
|
||||
[0xf00ddad1, 0xe2f5446a, 0x00002cfc, 0x762697a6, 0x00050b96, 0x00000b69],
|
||||
[0xa879152a, 0x0a70e0a5, 0x00007cdf, 0xb44151b3, 0x00001567, 0x0000363d],
|
||||
[0x7179a74c, 0x46083fff, 0x0000253c, 0x4d39ba6e, 0x0001e17f, 0x00000f84]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testData.length; i++) {
|
||||
var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
|
||||
var result = a.div(testData[i][2]);
|
||||
var quotient = result[0];
|
||||
var remainder = result[1];
|
||||
assertEquals(quotient.lo, testData[i][3]);
|
||||
assertEquals(quotient.hi, testData[i][4]);
|
||||
assertEquals(remainder.lo, testData[i][5]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests .toString() and .fromString().
|
||||
*/
|
||||
it('testStrings', function() {
|
||||
var testData = [
|
||||
[0x5e84c935, 0xcae33d0e, '14619595947299359029'],
|
||||
[0x62b3b8b8, 0x93480544, '10612738313170434232'],
|
||||
[0x319bfb13, 0xc01c4172, '13843011313344445203'],
|
||||
[0x5b8a65fb, 0xa5885b31, '11927883880638080507'],
|
||||
[0x6bdb80f1, 0xb0d1b16b, '12741159895737008369'],
|
||||
[0x4b82b442, 0x2e0d8c97, '3318463081876730946'],
|
||||
[0x780d5208, 0x7d76752c, '9040542135845999112'],
|
||||
[0x2e46800f, 0x0993778d, '690026616168284175'],
|
||||
[0xf00a7e32, 0xcd8e3931, '14811839111111540274'],
|
||||
[0x1baeccd6, 0x923048c4, '10533999535534820566'],
|
||||
[0x03669d29, 0xbff3ab72, '13831587386756603177'],
|
||||
[0x2526073e, 0x01affc81, '121593346566522686'],
|
||||
[0xc24244e0, 0xd7f40d0e, '15561076969511732448'],
|
||||
[0xc56a341e, 0xa68b66a7, '12000798502816461854'],
|
||||
[0x8738d64d, 0xbfe78604, '13828168534871037517'],
|
||||
[0x5baff03b, 0xd7572aea, '15516918227177304123'],
|
||||
[0x4a843d8a, 0x864e132b, '9677693725920476554'],
|
||||
[0x25b4e94d, 0x22b54dc6, '2500990681505655117'],
|
||||
[0x6bbe664b, 0x55a5cc0e, '6171563226690381387'],
|
||||
[0xee916c81, 0xb00aabb3, '12685140089732426881']
|
||||
];
|
||||
|
||||
for (var i = 0; i < testData.length; i++) {
|
||||
var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
|
||||
var roundtrip = jspb.arith.UInt64.fromString(a.toString());
|
||||
assertEquals(roundtrip.lo, a.lo);
|
||||
assertEquals(roundtrip.hi, a.hi);
|
||||
assertEquals(a.toString(), testData[i][2]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests signed Int64s. These are built on UInt64s, so we only need to test
|
||||
* the explicit overrides: .toString() and .fromString().
|
||||
*/
|
||||
it('testSignedInt64', function() {
|
||||
var testStrings = [
|
||||
'-7847499644178593666',
|
||||
'3771946501229139523',
|
||||
'2872856549054995060',
|
||||
'-5780049594274350904',
|
||||
'3383785956695105201',
|
||||
'2973055184857072610',
|
||||
'-3879428459215627206',
|
||||
'4589812431064156631',
|
||||
'8484075557333689940',
|
||||
'1075325817098092407',
|
||||
'-4346697501012292314',
|
||||
'2488620459718316637',
|
||||
'6112655187423520672',
|
||||
'-3655278273928612104',
|
||||
'3439154019435803196',
|
||||
'1004112478843763757',
|
||||
'-6587790776614368413',
|
||||
'664320065099714586',
|
||||
'4760412909973292912',
|
||||
'-7911903989602274672'
|
||||
];
|
||||
|
||||
for (var i = 0; i < testStrings.length; i++) {
|
||||
var roundtrip =
|
||||
jspb.arith.Int64.fromString(testStrings[i]).toString();
|
||||
assertEquals(roundtrip, testStrings[i]);
|
||||
}
|
||||
});
|
||||
});
|
334
js/compatibility_tests/v3.1.0/binary/decoder_test.js
Normal file
334
js/compatibility_tests/v3.1.0/binary/decoder_test.js
Normal file
@ -0,0 +1,334 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/**
|
||||
* @fileoverview Test cases for jspb's binary protocol buffer decoder.
|
||||
*
|
||||
* There are two particular magic numbers that need to be pointed out -
|
||||
* 2^64-1025 is the largest number representable as both a double and an
|
||||
* unsigned 64-bit integer, and 2^63-513 is the largest number representable as
|
||||
* both a double and a signed 64-bit integer.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryDecoder');
|
||||
goog.require('jspb.BinaryEncoder');
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of unsigned types.
|
||||
* @param {Function} readValue
|
||||
* @param {Function} writeValue
|
||||
* @param {number} epsilon
|
||||
* @param {number} upperLimit
|
||||
* @param {Function} filter
|
||||
* @suppress {missingProperties|visibility}
|
||||
*/
|
||||
function doTestUnsignedValue(readValue,
|
||||
writeValue, epsilon, upperLimit, filter) {
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
|
||||
// Encode zero and limits.
|
||||
writeValue.call(encoder, filter(0));
|
||||
writeValue.call(encoder, filter(epsilon));
|
||||
writeValue.call(encoder, filter(upperLimit));
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
writeValue.call(encoder, filter(cursor));
|
||||
}
|
||||
|
||||
var decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
|
||||
// Check zero and limits.
|
||||
assertEquals(filter(0), readValue.call(decoder));
|
||||
assertEquals(filter(epsilon), readValue.call(decoder));
|
||||
assertEquals(filter(upperLimit), readValue.call(decoder));
|
||||
|
||||
// Check positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
if (filter(cursor) != readValue.call(decoder)) throw 'fail!';
|
||||
}
|
||||
|
||||
// Encoding values outside the valid range should assert.
|
||||
assertThrows(function() {writeValue.call(encoder, -1);});
|
||||
assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of signed types.
|
||||
* @param {Function} readValue
|
||||
* @param {Function} writeValue
|
||||
* @param {number} epsilon
|
||||
* @param {number} lowerLimit
|
||||
* @param {number} upperLimit
|
||||
* @param {Function} filter
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
function doTestSignedValue(readValue,
|
||||
writeValue, epsilon, lowerLimit, upperLimit, filter) {
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
|
||||
// Encode zero and limits.
|
||||
writeValue.call(encoder, filter(lowerLimit));
|
||||
writeValue.call(encoder, filter(-epsilon));
|
||||
writeValue.call(encoder, filter(0));
|
||||
writeValue.call(encoder, filter(epsilon));
|
||||
writeValue.call(encoder, filter(upperLimit));
|
||||
|
||||
var inputValues = [];
|
||||
|
||||
// Encode negative values.
|
||||
for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeValue.call(encoder, val);
|
||||
inputValues.push(val);
|
||||
}
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeValue.call(encoder, val);
|
||||
inputValues.push(val);
|
||||
}
|
||||
|
||||
var decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
|
||||
// Check zero and limits.
|
||||
assertEquals(filter(lowerLimit), readValue.call(decoder));
|
||||
assertEquals(filter(-epsilon), readValue.call(decoder));
|
||||
assertEquals(filter(0), readValue.call(decoder));
|
||||
assertEquals(filter(epsilon), readValue.call(decoder));
|
||||
assertEquals(filter(upperLimit), readValue.call(decoder));
|
||||
|
||||
// Verify decoded values.
|
||||
for (var i = 0; i < inputValues.length; i++) {
|
||||
assertEquals(inputValues[i], readValue.call(decoder));
|
||||
}
|
||||
|
||||
// Encoding values outside the valid range should assert.
|
||||
assertThrows(function() {writeValue.call(encoder, lowerLimit * 1.1);});
|
||||
assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);});
|
||||
}
|
||||
|
||||
describe('binaryDecoderTest', function() {
|
||||
/**
|
||||
* Tests the decoder instance cache.
|
||||
*/
|
||||
it('testInstanceCache', /** @suppress {visibility} */ function() {
|
||||
// Empty the instance caches.
|
||||
jspb.BinaryDecoder.instanceCache_ = [];
|
||||
|
||||
// Allocating and then freeing a decoder should put it in the instance
|
||||
// cache.
|
||||
jspb.BinaryDecoder.alloc().free();
|
||||
|
||||
assertEquals(1, jspb.BinaryDecoder.instanceCache_.length);
|
||||
|
||||
// Allocating and then freeing three decoders should leave us with three in
|
||||
// the cache.
|
||||
|
||||
var decoder1 = jspb.BinaryDecoder.alloc();
|
||||
var decoder2 = jspb.BinaryDecoder.alloc();
|
||||
var decoder3 = jspb.BinaryDecoder.alloc();
|
||||
decoder1.free();
|
||||
decoder2.free();
|
||||
decoder3.free();
|
||||
|
||||
assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests reading 64-bit integers as hash strings.
|
||||
*/
|
||||
it('testHashStrings', function() {
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
|
||||
var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00);
|
||||
var hashB = String.fromCharCode(0x12, 0x34, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00);
|
||||
var hashC = String.fromCharCode(0x12, 0x34, 0x56, 0x78,
|
||||
0x87, 0x65, 0x43, 0x21);
|
||||
var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF);
|
||||
|
||||
encoder.writeVarintHash64(hashA);
|
||||
encoder.writeVarintHash64(hashB);
|
||||
encoder.writeVarintHash64(hashC);
|
||||
encoder.writeVarintHash64(hashD);
|
||||
|
||||
encoder.writeFixedHash64(hashA);
|
||||
encoder.writeFixedHash64(hashB);
|
||||
encoder.writeFixedHash64(hashC);
|
||||
encoder.writeFixedHash64(hashD);
|
||||
|
||||
var decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
|
||||
assertEquals(hashA, decoder.readVarintHash64());
|
||||
assertEquals(hashB, decoder.readVarintHash64());
|
||||
assertEquals(hashC, decoder.readVarintHash64());
|
||||
assertEquals(hashD, decoder.readVarintHash64());
|
||||
|
||||
assertEquals(hashA, decoder.readFixedHash64());
|
||||
assertEquals(hashB, decoder.readFixedHash64());
|
||||
assertEquals(hashC, decoder.readFixedHash64());
|
||||
assertEquals(hashD, decoder.readFixedHash64());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that misuse of the decoder class triggers assertions.
|
||||
* @suppress {checkTypes|visibility}
|
||||
*/
|
||||
it('testDecodeErrors', function() {
|
||||
// Reading a value past the end of the stream should trigger an assertion.
|
||||
var decoder = jspb.BinaryDecoder.alloc([0, 1, 2]);
|
||||
assertThrows(function() {decoder.readUint64()});
|
||||
|
||||
// Overlong varints should trigger assertions.
|
||||
decoder.setBlock([255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 0]);
|
||||
assertThrows(function() {decoder.readUnsignedVarint64()});
|
||||
decoder.reset();
|
||||
assertThrows(function() {decoder.readSignedVarint64()});
|
||||
decoder.reset();
|
||||
assertThrows(function() {decoder.readZigzagVarint64()});
|
||||
|
||||
// Positive 32-bit varints encoded with 1 bits in positions 33 through 35
|
||||
// should trigger assertions.
|
||||
decoder.setBlock([255, 255, 255, 255, 0x1F]);
|
||||
assertThrows(function() {decoder.readUnsignedVarint32()});
|
||||
|
||||
decoder.setBlock([255, 255, 255, 255, 0x2F]);
|
||||
assertThrows(function() {decoder.readUnsignedVarint32()});
|
||||
|
||||
decoder.setBlock([255, 255, 255, 255, 0x4F]);
|
||||
assertThrows(function() {decoder.readUnsignedVarint32()});
|
||||
|
||||
// Negative 32-bit varints encoded with non-1 bits in the high dword should
|
||||
// trigger assertions.
|
||||
decoder.setBlock([255, 255, 255, 255, 255, 255, 0, 255, 255, 1]);
|
||||
assertThrows(function() {decoder.readUnsignedVarint32()});
|
||||
|
||||
decoder.setBlock([255, 255, 255, 255, 255, 255, 255, 255, 255, 0]);
|
||||
assertThrows(function() {decoder.readUnsignedVarint32()});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of unsigned integers.
|
||||
*/
|
||||
it('testUnsignedIntegers', function() {
|
||||
doTestUnsignedValue(
|
||||
jspb.BinaryDecoder.prototype.readUint8,
|
||||
jspb.BinaryEncoder.prototype.writeUint8,
|
||||
1, 0xFF, Math.round);
|
||||
|
||||
doTestUnsignedValue(
|
||||
jspb.BinaryDecoder.prototype.readUint16,
|
||||
jspb.BinaryEncoder.prototype.writeUint16,
|
||||
1, 0xFFFF, Math.round);
|
||||
|
||||
doTestUnsignedValue(
|
||||
jspb.BinaryDecoder.prototype.readUint32,
|
||||
jspb.BinaryEncoder.prototype.writeUint32,
|
||||
1, 0xFFFFFFFF, Math.round);
|
||||
|
||||
doTestUnsignedValue(
|
||||
jspb.BinaryDecoder.prototype.readUint64,
|
||||
jspb.BinaryEncoder.prototype.writeUint64,
|
||||
1, Math.pow(2, 64) - 1025, Math.round);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of signed integers.
|
||||
*/
|
||||
it('testSignedIntegers', function() {
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readInt8,
|
||||
jspb.BinaryEncoder.prototype.writeInt8,
|
||||
1, -0x80, 0x7F, Math.round);
|
||||
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readInt16,
|
||||
jspb.BinaryEncoder.prototype.writeInt16,
|
||||
1, -0x8000, 0x7FFF, Math.round);
|
||||
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readInt32,
|
||||
jspb.BinaryEncoder.prototype.writeInt32,
|
||||
1, -0x80000000, 0x7FFFFFFF, Math.round);
|
||||
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readInt64,
|
||||
jspb.BinaryEncoder.prototype.writeInt64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of floats.
|
||||
*/
|
||||
it('testFloats', function() {
|
||||
/**
|
||||
* @param {number} x
|
||||
* @return {number}
|
||||
*/
|
||||
function truncate(x) {
|
||||
var temp = new Float32Array(1);
|
||||
temp[0] = x;
|
||||
return temp[0];
|
||||
}
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readFloat,
|
||||
jspb.BinaryEncoder.prototype.writeFloat,
|
||||
jspb.BinaryConstants.FLOAT32_EPS,
|
||||
-jspb.BinaryConstants.FLOAT32_MAX,
|
||||
jspb.BinaryConstants.FLOAT32_MAX,
|
||||
truncate);
|
||||
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readDouble,
|
||||
jspb.BinaryEncoder.prototype.writeDouble,
|
||||
jspb.BinaryConstants.FLOAT64_EPS * 10,
|
||||
-jspb.BinaryConstants.FLOAT64_MAX,
|
||||
jspb.BinaryConstants.FLOAT64_MAX,
|
||||
function(x) { return x; });
|
||||
});
|
||||
});
|
628
js/compatibility_tests/v3.1.0/binary/proto_test.js
Normal file
628
js/compatibility_tests/v3.1.0/binary/proto_test.js
Normal file
@ -0,0 +1,628 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.Message');
|
||||
|
||||
// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.ExtendsWithMessage');
|
||||
goog.require('proto.jspb.test.ForeignEnum');
|
||||
goog.require('proto.jspb.test.ForeignMessage');
|
||||
goog.require('proto.jspb.test.TestAllTypes');
|
||||
goog.require('proto.jspb.test.TestExtendable');
|
||||
goog.require('proto.jspb.test.extendOptionalBool');
|
||||
goog.require('proto.jspb.test.extendOptionalBytes');
|
||||
goog.require('proto.jspb.test.extendOptionalDouble');
|
||||
goog.require('proto.jspb.test.extendOptionalFixed32');
|
||||
goog.require('proto.jspb.test.extendOptionalFixed64');
|
||||
goog.require('proto.jspb.test.extendOptionalFloat');
|
||||
goog.require('proto.jspb.test.extendOptionalForeignEnum');
|
||||
goog.require('proto.jspb.test.extendOptionalInt32');
|
||||
goog.require('proto.jspb.test.extendOptionalInt64');
|
||||
goog.require('proto.jspb.test.extendOptionalSfixed32');
|
||||
goog.require('proto.jspb.test.extendOptionalSfixed64');
|
||||
goog.require('proto.jspb.test.extendOptionalSint32');
|
||||
goog.require('proto.jspb.test.extendOptionalSint64');
|
||||
goog.require('proto.jspb.test.extendOptionalString');
|
||||
goog.require('proto.jspb.test.extendOptionalUint32');
|
||||
goog.require('proto.jspb.test.extendOptionalUint64');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedBoolList');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedDoubleList');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedFixed32List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedFixed64List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedFloatList');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedForeignEnumList');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedInt32List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedInt64List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedSfixed32List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedSfixed64List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedSint32List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedSint64List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedUint32List');
|
||||
goog.require('proto.jspb.test.extendPackedRepeatedUint64List');
|
||||
goog.require('proto.jspb.test.extendRepeatedBoolList');
|
||||
goog.require('proto.jspb.test.extendRepeatedBytesList');
|
||||
goog.require('proto.jspb.test.extendRepeatedDoubleList');
|
||||
goog.require('proto.jspb.test.extendRepeatedFixed32List');
|
||||
goog.require('proto.jspb.test.extendRepeatedFixed64List');
|
||||
goog.require('proto.jspb.test.extendRepeatedFloatList');
|
||||
goog.require('proto.jspb.test.extendRepeatedForeignEnumList');
|
||||
goog.require('proto.jspb.test.extendRepeatedInt32List');
|
||||
goog.require('proto.jspb.test.extendRepeatedInt64List');
|
||||
goog.require('proto.jspb.test.extendRepeatedSfixed32List');
|
||||
goog.require('proto.jspb.test.extendRepeatedSfixed64List');
|
||||
goog.require('proto.jspb.test.extendRepeatedSint32List');
|
||||
goog.require('proto.jspb.test.extendRepeatedSint64List');
|
||||
goog.require('proto.jspb.test.extendRepeatedStringList');
|
||||
goog.require('proto.jspb.test.extendRepeatedUint32List');
|
||||
goog.require('proto.jspb.test.extendRepeatedUint64List');
|
||||
|
||||
|
||||
var suite = {};
|
||||
|
||||
var BYTES = new Uint8Array([1, 2, 8, 9]);
|
||||
|
||||
var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
|
||||
|
||||
|
||||
/**
|
||||
* Helper: fill all fields on a TestAllTypes message.
|
||||
* @param {proto.jspb.test.TestAllTypes} msg
|
||||
*/
|
||||
function fillAllFields(msg) {
|
||||
msg.setOptionalInt32(-42);
|
||||
// can be exactly represented by JS number (64-bit double, i.e., 52-bit
|
||||
// mantissa).
|
||||
msg.setOptionalInt64(-0x7fffffff00000000);
|
||||
msg.setOptionalUint32(0x80000000);
|
||||
msg.setOptionalUint64(0xf000000000000000);
|
||||
msg.setOptionalSint32(-100);
|
||||
msg.setOptionalSint64(-0x8000000000000000);
|
||||
msg.setOptionalFixed32(1234);
|
||||
msg.setOptionalFixed64(0x1234567800000000);
|
||||
msg.setOptionalSfixed32(-1234);
|
||||
msg.setOptionalSfixed64(-0x1234567800000000);
|
||||
msg.setOptionalFloat(1.5);
|
||||
msg.setOptionalDouble(-1.5);
|
||||
msg.setOptionalBool(true);
|
||||
msg.setOptionalString('hello world');
|
||||
msg.setOptionalBytes(BYTES);
|
||||
msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup());
|
||||
msg.getOptionalGroup().setA(100);
|
||||
var submsg = new proto.jspb.test.ForeignMessage();
|
||||
submsg.setC(16);
|
||||
msg.setOptionalForeignMessage(submsg);
|
||||
msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO);
|
||||
msg.setOneofString('oneof');
|
||||
|
||||
|
||||
msg.setRepeatedInt32List([-42]);
|
||||
msg.setRepeatedInt64List([-0x7fffffff00000000]);
|
||||
msg.setRepeatedUint32List([0x80000000]);
|
||||
msg.setRepeatedUint64List([0xf000000000000000]);
|
||||
msg.setRepeatedSint32List([-100]);
|
||||
msg.setRepeatedSint64List([-0x8000000000000000]);
|
||||
msg.setRepeatedFixed32List([1234]);
|
||||
msg.setRepeatedFixed64List([0x1234567800000000]);
|
||||
msg.setRepeatedSfixed32List([-1234]);
|
||||
msg.setRepeatedSfixed64List([-0x1234567800000000]);
|
||||
msg.setRepeatedFloatList([1.5]);
|
||||
msg.setRepeatedDoubleList([-1.5]);
|
||||
msg.setRepeatedBoolList([true]);
|
||||
msg.setRepeatedStringList(['hello world']);
|
||||
msg.setRepeatedBytesList([BYTES, BYTES]);
|
||||
msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]);
|
||||
msg.getRepeatedGroupList()[0].setA(100);
|
||||
submsg = new proto.jspb.test.ForeignMessage();
|
||||
submsg.setC(1000);
|
||||
msg.setRepeatedForeignMessageList([submsg]);
|
||||
msg.setRepeatedForeignEnumList([proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
msg.setPackedRepeatedInt32List([-42]);
|
||||
msg.setPackedRepeatedInt64List([-0x7fffffff00000000]);
|
||||
msg.setPackedRepeatedUint32List([0x80000000]);
|
||||
msg.setPackedRepeatedUint64List([0xf000000000000000]);
|
||||
msg.setPackedRepeatedSint32List([-100]);
|
||||
msg.setPackedRepeatedSint64List([-0x8000000000000000]);
|
||||
msg.setPackedRepeatedFixed32List([1234]);
|
||||
msg.setPackedRepeatedFixed64List([0x1234567800000000]);
|
||||
msg.setPackedRepeatedSfixed32List([-1234]);
|
||||
msg.setPackedRepeatedSfixed64List([-0x1234567800000000]);
|
||||
msg.setPackedRepeatedFloatList([1.5]);
|
||||
msg.setPackedRepeatedDoubleList([-1.5]);
|
||||
msg.setPackedRepeatedBoolList([true]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper: compare a bytes field to an expected value
|
||||
* @param {Uint8Array|string} arr
|
||||
* @param {Uint8Array} expected
|
||||
* @return {boolean}
|
||||
*/
|
||||
function bytesCompare(arr, expected) {
|
||||
if (goog.isString(arr)) {
|
||||
arr = goog.crypt.base64.decodeStringToUint8Array(arr);
|
||||
}
|
||||
if (arr.length != expected.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i] != expected[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper: verify contents of given TestAllTypes message as set by
|
||||
* fillAllFields().
|
||||
* @param {proto.jspb.test.TestAllTypes} original
|
||||
* @param {proto.jspb.test.TestAllTypes} copy
|
||||
*/
|
||||
function checkAllFields(original, copy) {
|
||||
assertTrue(jspb.Message.equals(original, copy));
|
||||
|
||||
assertEquals(copy.getOptionalInt32(), -42);
|
||||
assertEquals(copy.getOptionalInt64(), -0x7fffffff00000000);
|
||||
assertEquals(copy.getOptionalUint32(), 0x80000000);
|
||||
assertEquals(copy.getOptionalUint64(), 0xf000000000000000);
|
||||
assertEquals(copy.getOptionalSint32(), -100);
|
||||
assertEquals(copy.getOptionalSint64(), -0x8000000000000000);
|
||||
assertEquals(copy.getOptionalFixed32(), 1234);
|
||||
assertEquals(copy.getOptionalFixed64(), 0x1234567800000000);
|
||||
assertEquals(copy.getOptionalSfixed32(), -1234);
|
||||
assertEquals(copy.getOptionalSfixed64(), -0x1234567800000000);
|
||||
assertEquals(copy.getOptionalFloat(), 1.5);
|
||||
assertEquals(copy.getOptionalDouble(), -1.5);
|
||||
assertEquals(copy.getOptionalBool(), true);
|
||||
assertEquals(copy.getOptionalString(), 'hello world');
|
||||
assertEquals(true, bytesCompare(copy.getOptionalBytes(), BYTES));
|
||||
assertEquals(true, bytesCompare(copy.getOptionalBytes_asU8(), BYTES));
|
||||
assertEquals(
|
||||
copy.getOptionalBytes_asB64(), goog.crypt.base64.encodeByteArray(BYTES));
|
||||
|
||||
assertEquals(copy.getOptionalGroup().getA(), 100);
|
||||
assertEquals(copy.getOptionalForeignMessage().getC(), 16);
|
||||
assertEquals(copy.getOptionalForeignEnum(),
|
||||
proto.jspb.test.ForeignEnum.FOREIGN_FOO);
|
||||
|
||||
|
||||
assertEquals(copy.getOneofString(), 'oneof');
|
||||
assertEquals(copy.getOneofFieldCase(),
|
||||
proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING);
|
||||
|
||||
assertElementsEquals(copy.getRepeatedInt32List(), [-42]);
|
||||
assertElementsEquals(copy.getRepeatedInt64List(), [-0x7fffffff00000000]);
|
||||
assertElementsEquals(copy.getRepeatedUint32List(), [0x80000000]);
|
||||
assertElementsEquals(copy.getRepeatedUint64List(), [0xf000000000000000]);
|
||||
assertElementsEquals(copy.getRepeatedSint32List(), [-100]);
|
||||
assertElementsEquals(copy.getRepeatedSint64List(), [-0x8000000000000000]);
|
||||
assertElementsEquals(copy.getRepeatedFixed32List(), [1234]);
|
||||
assertElementsEquals(copy.getRepeatedFixed64List(), [0x1234567800000000]);
|
||||
assertElementsEquals(copy.getRepeatedSfixed32List(), [-1234]);
|
||||
assertElementsEquals(copy.getRepeatedSfixed64List(), [-0x1234567800000000]);
|
||||
assertElementsEquals(copy.getRepeatedFloatList(), [1.5]);
|
||||
assertElementsEquals(copy.getRepeatedDoubleList(), [-1.5]);
|
||||
assertElementsEquals(copy.getRepeatedBoolList(), [true]);
|
||||
assertElementsEquals(copy.getRepeatedStringList(), ['hello world']);
|
||||
assertEquals(copy.getRepeatedBytesList().length, 2);
|
||||
assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[0], BYTES));
|
||||
assertEquals(true, bytesCompare(copy.getRepeatedBytesList()[0], BYTES));
|
||||
assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[1], BYTES));
|
||||
assertEquals(copy.getRepeatedBytesList_asB64()[0], BYTES_B64);
|
||||
assertEquals(copy.getRepeatedBytesList_asB64()[1], BYTES_B64);
|
||||
assertEquals(copy.getRepeatedGroupList().length, 1);
|
||||
assertEquals(copy.getRepeatedGroupList()[0].getA(), 100);
|
||||
assertEquals(copy.getRepeatedForeignMessageList().length, 1);
|
||||
assertEquals(copy.getRepeatedForeignMessageList()[0].getC(), 1000);
|
||||
assertElementsEquals(copy.getRepeatedForeignEnumList(),
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
assertElementsEquals(copy.getPackedRepeatedInt32List(), [-42]);
|
||||
assertElementsEquals(copy.getPackedRepeatedInt64List(),
|
||||
[-0x7fffffff00000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedUint32List(), [0x80000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedUint64List(),
|
||||
[0xf000000000000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedSint32List(), [-100]);
|
||||
assertElementsEquals(copy.getPackedRepeatedSint64List(),
|
||||
[-0x8000000000000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedFixed32List(), [1234]);
|
||||
assertElementsEquals(copy.getPackedRepeatedFixed64List(),
|
||||
[0x1234567800000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedSfixed32List(), [-1234]);
|
||||
assertElementsEquals(copy.getPackedRepeatedSfixed64List(),
|
||||
[-0x1234567800000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]);
|
||||
assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper: verify that all expected extensions are present.
|
||||
* @param {!proto.jspb.test.TestExtendable} msg
|
||||
*/
|
||||
function checkExtensions(msg) {
|
||||
assertEquals(-42,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalInt32));
|
||||
assertEquals(-0x7fffffff00000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalInt64));
|
||||
assertEquals(0x80000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalUint32));
|
||||
assertEquals(0xf000000000000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalUint64));
|
||||
assertEquals(-100,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalSint32));
|
||||
assertEquals(-0x8000000000000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalSint64));
|
||||
assertEquals(1234,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalFixed32));
|
||||
assertEquals(0x1234567800000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalFixed64));
|
||||
assertEquals(-1234,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalSfixed32));
|
||||
assertEquals(-0x1234567800000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalSfixed64));
|
||||
assertEquals(1.5,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalFloat));
|
||||
assertEquals(-1.5,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalDouble));
|
||||
assertEquals(true,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalBool));
|
||||
assertEquals('hello world',
|
||||
msg.getExtension(proto.jspb.test.extendOptionalString));
|
||||
assertEquals(
|
||||
true, bytesCompare(
|
||||
msg.getExtension(proto.jspb.test.extendOptionalBytes), BYTES));
|
||||
assertEquals(16,
|
||||
msg.getExtension(
|
||||
proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo());
|
||||
|
||||
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedInt32List),
|
||||
[-42]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedInt64List),
|
||||
[-0x7fffffff00000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedUint32List),
|
||||
[0x80000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedUint64List),
|
||||
[0xf000000000000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedSint32List),
|
||||
[-100]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedSint64List),
|
||||
[-0x8000000000000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedFixed32List),
|
||||
[1234]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedFixed64List),
|
||||
[0x1234567800000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedSfixed32List),
|
||||
[-1234]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedSfixed64List),
|
||||
[-0x1234567800000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedFloatList),
|
||||
[1.5]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedDoubleList),
|
||||
[-1.5]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedBoolList),
|
||||
[true]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedStringList),
|
||||
['hello world']);
|
||||
assertEquals(
|
||||
true,
|
||||
bytesCompare(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0], BYTES));
|
||||
assertEquals(1000,
|
||||
msg.getExtension(
|
||||
proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0]
|
||||
.getFoo());
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList),
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List),
|
||||
[-42]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedInt64List),
|
||||
[-0x7fffffff00000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedUint32List),
|
||||
[0x80000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedUint64List),
|
||||
[0xf000000000000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedSint32List),
|
||||
[-100]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedSint64List),
|
||||
[-0x8000000000000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed32List),
|
||||
[1234]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed64List),
|
||||
[0x1234567800000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed32List),
|
||||
[-1234]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed64List),
|
||||
[-0x1234567800000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedFloatList),
|
||||
[1.5]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedDoubleList),
|
||||
[-1.5]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedBoolList),
|
||||
[true]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList),
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
describe('protoBinaryTest', function() {
|
||||
/**
|
||||
* Tests a basic serialization-deserializaton round-trip with all supported
|
||||
* field types (on the TestAllTypes message type).
|
||||
*/
|
||||
it('testRoundTrip', function() {
|
||||
var msg = new proto.jspb.test.TestAllTypes();
|
||||
fillAllFields(msg);
|
||||
var encoded = msg.serializeBinary();
|
||||
var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded);
|
||||
checkAllFields(msg, decoded);
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that base64 string and Uint8Array are interchangeable in bytes fields.
|
||||
*/
|
||||
it('testBytesFieldsGettersInterop', function() {
|
||||
var msg = new proto.jspb.test.TestAllTypes();
|
||||
// Set from a base64 string and check all the getters work.
|
||||
msg.setOptionalBytes(BYTES_B64);
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
|
||||
// Test binary serialize round trip doesn't break it.
|
||||
msg = proto.jspb.test.TestAllTypes.deserializeBinary(msg.serializeBinary());
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
|
||||
msg = new proto.jspb.test.TestAllTypes();
|
||||
// Set from a Uint8Array and check all the getters work.
|
||||
msg.setOptionalBytes(BYTES);
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that bytes setters will receive result of any of the getters.
|
||||
*/
|
||||
it('testBytesFieldsSettersInterop', function() {
|
||||
var msg = new proto.jspb.test.TestAllTypes();
|
||||
msg.setOptionalBytes(BYTES);
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
|
||||
msg.setOptionalBytes(msg.getOptionalBytes());
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
msg.setOptionalBytes(msg.getOptionalBytes_asB64());
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
msg.setOptionalBytes(msg.getOptionalBytes_asU8());
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that bytes setters will receive result of any of the getters.
|
||||
*/
|
||||
it('testRepeatedBytesGetters', function() {
|
||||
var msg = new proto.jspb.test.TestAllTypes();
|
||||
|
||||
function assertGetters() {
|
||||
assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[0]));
|
||||
assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[1]));
|
||||
assertTrue(msg.getRepeatedBytesList_asU8()[0] instanceof Uint8Array);
|
||||
assertTrue(msg.getRepeatedBytesList_asU8()[1] instanceof Uint8Array);
|
||||
|
||||
assertTrue(bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
|
||||
assertTrue(bytesCompare(msg.getRepeatedBytesList()[1], BYTES));
|
||||
assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[0], BYTES));
|
||||
assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[1], BYTES));
|
||||
assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[0], BYTES));
|
||||
assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[1], BYTES));
|
||||
}
|
||||
|
||||
msg.setRepeatedBytesList([BYTES, BYTES]);
|
||||
assertGetters();
|
||||
|
||||
msg.setRepeatedBytesList([BYTES_B64, BYTES_B64]);
|
||||
assertGetters();
|
||||
|
||||
msg.setRepeatedBytesList([]);
|
||||
assertEquals(0, msg.getRepeatedBytesList().length);
|
||||
assertEquals(0, msg.getRepeatedBytesList_asB64().length);
|
||||
assertEquals(0, msg.getRepeatedBytesList_asU8().length);
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper: fill all extension values.
|
||||
* @param {proto.jspb.test.TestExtendable} msg
|
||||
*/
|
||||
function fillExtensions(msg) {
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalInt32, -42);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalUint32, 0x80000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalUint64, 0xf000000000000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalSint32, -100);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalSint64, -0x8000000000000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalFixed32, 1234);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalFixed64, 0x1234567800000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalSfixed32, -1234);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalSfixed64, -0x1234567800000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalFloat, 1.5);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalDouble, -1.5);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalBool, true);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalString, 'hello world');
|
||||
msg.setExtension(proto.jspb.test.extendOptionalBytes, BYTES);
|
||||
var submsg = new proto.jspb.test.ExtendsWithMessage();
|
||||
submsg.setFoo(16);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.ExtendsWithMessage.optionalExtension, submsg);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalForeignEnum,
|
||||
proto.jspb.test.ForeignEnum.FOREIGN_FOO);
|
||||
|
||||
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedInt32List, [-42]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedInt64List, [-0x7fffffff00000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedUint32List, [0x80000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedUint64List, [0xf000000000000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedSint32List, [-100]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedSint64List, [-0x8000000000000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedFixed32List, [1234]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedFixed64List, [0x1234567800000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedSfixed32List, [-1234]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedSfixed64List, [-0x1234567800000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedFloatList, [1.5]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedDoubleList, [-1.5]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedBoolList, [true]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedStringList, ['hello world']);
|
||||
msg.setExtension(proto.jspb.test.extendRepeatedBytesList, [BYTES]);
|
||||
submsg = new proto.jspb.test.ExtendsWithMessage();
|
||||
submsg.setFoo(1000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.ExtendsWithMessage.repeatedExtensionList, [submsg]);
|
||||
msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList,
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedInt32List, [-42]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedInt64List, [-0x7fffffff00000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedUint32List, [0x80000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedUint64List, [0xf000000000000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedSint32List, [-100]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedSint64List, [-0x8000000000000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedFixed32List, [1234]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedFixed64List, [0x1234567800000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedSfixed32List, [-1234]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedSfixed64List,
|
||||
[-0x1234567800000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedFloatList, [1.5]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedDoubleList, [-1.5]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedBoolList, [true]);
|
||||
msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList,
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests extension serialization and deserialization.
|
||||
*/
|
||||
it('testExtensions', function() {
|
||||
var msg = new proto.jspb.test.TestExtendable();
|
||||
fillExtensions(msg);
|
||||
var encoded = msg.serializeBinary();
|
||||
var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded);
|
||||
checkExtensions(decoded);
|
||||
});
|
||||
});
|
922
js/compatibility_tests/v3.1.0/binary/reader_test.js
Normal file
922
js/compatibility_tests/v3.1.0/binary/reader_test.js
Normal file
@ -0,0 +1,922 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/**
|
||||
* @fileoverview Test cases for jspb's binary protocol buffer reader.
|
||||
*
|
||||
* There are two particular magic numbers that need to be pointed out -
|
||||
* 2^64-1025 is the largest number representable as both a double and an
|
||||
* unsigned 64-bit integer, and 2^63-513 is the largest number representable as
|
||||
* both a double and a signed 64-bit integer.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryDecoder');
|
||||
goog.require('jspb.BinaryReader');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
|
||||
|
||||
|
||||
describe('binaryReaderTest', function() {
|
||||
/**
|
||||
* Tests the reader instance cache.
|
||||
*/
|
||||
it('testInstanceCaches', /** @suppress {visibility} */ function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
writer.writeMessage(1, dummyMessage, goog.nullFunction);
|
||||
writer.writeMessage(2, dummyMessage, goog.nullFunction);
|
||||
|
||||
var buffer = writer.getResultBuffer();
|
||||
|
||||
// Empty the instance caches.
|
||||
jspb.BinaryReader.instanceCache_ = [];
|
||||
|
||||
// Allocating and then freeing three decoders should leave us with three in
|
||||
// the cache.
|
||||
|
||||
var decoder1 = jspb.BinaryDecoder.alloc();
|
||||
var decoder2 = jspb.BinaryDecoder.alloc();
|
||||
var decoder3 = jspb.BinaryDecoder.alloc();
|
||||
decoder1.free();
|
||||
decoder2.free();
|
||||
decoder3.free();
|
||||
|
||||
assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
|
||||
// Allocating and then freeing a reader should remove one decoder from its
|
||||
// cache, but it should stay stuck to the reader afterwards since we can't
|
||||
// have a reader without a decoder.
|
||||
jspb.BinaryReader.alloc().free();
|
||||
|
||||
assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(1, jspb.BinaryReader.instanceCache_.length);
|
||||
|
||||
// Allocating a reader should remove a reader from the cache.
|
||||
var reader = jspb.BinaryReader.alloc(buffer);
|
||||
|
||||
assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
|
||||
// Processing the message reuses the current reader.
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
});
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
|
||||
assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
|
||||
// Freeing the reader should put it back into the cache.
|
||||
reader.free();
|
||||
|
||||
assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(1, jspb.BinaryReader.instanceCache_.length);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @return {number}
|
||||
*/
|
||||
function truncate(x) {
|
||||
var temp = new Float32Array(1);
|
||||
temp[0] = x;
|
||||
return temp[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that misuse of the reader class triggers assertions.
|
||||
*/
|
||||
it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() {
|
||||
// Calling readMessage on a non-delimited field should trigger an
|
||||
// assertion.
|
||||
var reader = jspb.BinaryReader.alloc([8, 1]);
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
reader.nextField();
|
||||
assertThrows(function() {
|
||||
reader.readMessage(dummyMessage, goog.nullFunction);
|
||||
});
|
||||
|
||||
// Reading past the end of the stream should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([9, 1]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed64()});
|
||||
|
||||
// Reading past the end of a submessage should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
|
||||
reader.nextField();
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed32()});
|
||||
});
|
||||
|
||||
// Skipping an invalid field should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([12, 1]);
|
||||
reader.nextWireType_ = 1000;
|
||||
assertThrows(function() {reader.skipField()});
|
||||
|
||||
// Reading fields with the wrong wire type should assert.
|
||||
reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readInt32()});
|
||||
assertThrows(function() {reader.readInt32String()});
|
||||
assertThrows(function() {reader.readInt64()});
|
||||
assertThrows(function() {reader.readInt64String()});
|
||||
assertThrows(function() {reader.readUint32()});
|
||||
assertThrows(function() {reader.readUint32String()});
|
||||
assertThrows(function() {reader.readUint64()});
|
||||
assertThrows(function() {reader.readUint64String()});
|
||||
assertThrows(function() {reader.readSint32()});
|
||||
assertThrows(function() {reader.readBool()});
|
||||
assertThrows(function() {reader.readEnum()});
|
||||
|
||||
reader = jspb.BinaryReader.alloc([8, 1]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {reader.readFixed32()});
|
||||
assertThrows(function() {reader.readFixed64()});
|
||||
assertThrows(function() {reader.readSfixed32()});
|
||||
assertThrows(function() {reader.readSfixed64()});
|
||||
assertThrows(function() {reader.readFloat()});
|
||||
assertThrows(function() {reader.readDouble()});
|
||||
|
||||
assertThrows(function() {reader.readString()});
|
||||
assertThrows(function() {reader.readBytes()});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of unsigned field types.
|
||||
* @param {Function} readField
|
||||
* @param {Function} writeField
|
||||
* @param {number} epsilon
|
||||
* @param {number} upperLimit
|
||||
* @param {Function} filter
|
||||
* @private
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
var doTestUnsignedField_ = function(readField,
|
||||
writeField, epsilon, upperLimit, filter) {
|
||||
assertNotNull(readField);
|
||||
assertNotNull(writeField);
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
// Encode zero and limits.
|
||||
writeField.call(writer, 1, filter(0));
|
||||
writeField.call(writer, 2, filter(epsilon));
|
||||
writeField.call(writer, 3, filter(upperLimit));
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
writeField.call(writer, 4, filter(cursor));
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
// Check zero and limits.
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(filter(0), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
assertEquals(filter(epsilon), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(filter(upperLimit), readField.call(reader));
|
||||
|
||||
// Check positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
reader.nextField();
|
||||
if (4 != reader.getFieldNumber()) throw 'fail!';
|
||||
if (filter(cursor) != readField.call(reader)) throw 'fail!';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of signed field types.
|
||||
* @param {Function} readField
|
||||
* @param {Function} writeField
|
||||
* @param {number} epsilon
|
||||
* @param {number} lowerLimit
|
||||
* @param {number} upperLimit
|
||||
* @param {Function} filter
|
||||
* @private
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
var doTestSignedField_ = function(readField,
|
||||
writeField, epsilon, lowerLimit, upperLimit, filter) {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
// Encode zero and limits.
|
||||
writeField.call(writer, 1, filter(lowerLimit));
|
||||
writeField.call(writer, 2, filter(-epsilon));
|
||||
writeField.call(writer, 3, filter(0));
|
||||
writeField.call(writer, 4, filter(epsilon));
|
||||
writeField.call(writer, 5, filter(upperLimit));
|
||||
|
||||
var inputValues = [];
|
||||
|
||||
// Encode negative values.
|
||||
for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeField.call(writer, 6, val);
|
||||
inputValues.push({
|
||||
fieldNumber: 6,
|
||||
value: val
|
||||
});
|
||||
}
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeField.call(writer, 7, val);
|
||||
inputValues.push({
|
||||
fieldNumber: 7,
|
||||
value: val
|
||||
});
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
// Check zero and limits.
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(filter(lowerLimit), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
assertEquals(filter(-epsilon), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(filter(0), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(4, reader.getFieldNumber());
|
||||
assertEquals(filter(epsilon), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(5, reader.getFieldNumber());
|
||||
assertEquals(filter(upperLimit), readField.call(reader));
|
||||
|
||||
for (var i = 0; i < inputValues.length; i++) {
|
||||
var expected = inputValues[i];
|
||||
reader.nextField();
|
||||
assertEquals(expected.fieldNumber, reader.getFieldNumber());
|
||||
assertEquals(expected.value, readField.call(reader));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tests fields that use varint encoding.
|
||||
*/
|
||||
it('testVarintFields', function() {
|
||||
assertNotUndefined(jspb.BinaryReader.prototype.readUint32);
|
||||
assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32);
|
||||
assertNotUndefined(jspb.BinaryReader.prototype.readUint64);
|
||||
assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64);
|
||||
assertNotUndefined(jspb.BinaryReader.prototype.readBool);
|
||||
assertNotUndefined(jspb.BinaryWriter.prototype.writeBool);
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readUint32,
|
||||
jspb.BinaryWriter.prototype.writeUint32,
|
||||
1, Math.pow(2, 32) - 1, Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readUint64,
|
||||
jspb.BinaryWriter.prototype.writeUint64,
|
||||
1, Math.pow(2, 64) - 1025, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readInt32,
|
||||
jspb.BinaryWriter.prototype.writeInt32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readInt64,
|
||||
jspb.BinaryWriter.prototype.writeInt64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readEnum,
|
||||
jspb.BinaryWriter.prototype.writeEnum,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readBool,
|
||||
jspb.BinaryWriter.prototype.writeBool,
|
||||
1, 1, function(x) { return !!x; });
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests reading a field from hexadecimal string (format: '08 BE EF').
|
||||
* @param {Function} readField
|
||||
* @param {number} expected
|
||||
* @param {string} hexString
|
||||
*/
|
||||
function doTestHexStringVarint_(readField, expected, hexString) {
|
||||
var bytesCount = (hexString.length + 1) / 3;
|
||||
var bytes = new Uint8Array(bytesCount);
|
||||
for (var i = 0; i < bytesCount; i++) {
|
||||
bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16);
|
||||
}
|
||||
var reader = jspb.BinaryReader.alloc(bytes);
|
||||
reader.nextField();
|
||||
assertEquals(expected, readField.call(reader));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests non-canonical redundant varint decoding.
|
||||
*/
|
||||
it('testRedundantVarintFields', function() {
|
||||
assertNotNull(jspb.BinaryReader.prototype.readUint32);
|
||||
assertNotNull(jspb.BinaryReader.prototype.readUint64);
|
||||
assertNotNull(jspb.BinaryReader.prototype.readSint32);
|
||||
assertNotNull(jspb.BinaryReader.prototype.readSint64);
|
||||
|
||||
// uint32 and sint32 take no more than 5 bytes
|
||||
// 08 - field prefix (type = 0 means varint)
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readUint32,
|
||||
12, '08 8C 80 80 80 00');
|
||||
|
||||
// 11 stands for -6 in zigzag encoding
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readSint32,
|
||||
-6, '08 8B 80 80 80 00');
|
||||
|
||||
// uint64 and sint64 take no more than 10 bytes
|
||||
// 08 - field prefix (type = 0 means varint)
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readUint64,
|
||||
12, '08 8C 80 80 80 80 80 80 80 80 00');
|
||||
|
||||
// 11 stands for -6 in zigzag encoding
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readSint64,
|
||||
-6, '08 8B 80 80 80 80 80 80 80 80 00');
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests 64-bit fields that are handled as strings.
|
||||
*/
|
||||
it('testStringInt64Fields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var testSignedData = [
|
||||
'2730538252207801776',
|
||||
'-2688470994844604560',
|
||||
'3398529779486536359',
|
||||
'3568577411627971000',
|
||||
'272477188847484900',
|
||||
'-6649058714086158188',
|
||||
'-7695254765712060806',
|
||||
'-4525541438037104029',
|
||||
'-4993706538836508568',
|
||||
'4990160321893729138'
|
||||
];
|
||||
var testUnsignedData = [
|
||||
'7822732630241694882',
|
||||
'6753602971916687352',
|
||||
'2399935075244442116',
|
||||
'8724292567325338867',
|
||||
'16948784802625696584',
|
||||
'4136275908516066934',
|
||||
'3575388346793700364',
|
||||
'5167142028379259461',
|
||||
'1557573948689737699',
|
||||
'17100725280812548567'
|
||||
];
|
||||
|
||||
for (var i = 0; i < testSignedData.length; i++) {
|
||||
writer.writeInt64String(2 * i + 1, testSignedData[i]);
|
||||
writer.writeUint64String(2 * i + 2, testUnsignedData[i]);
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
for (var i = 0; i < testSignedData.length; i++) {
|
||||
reader.nextField();
|
||||
assertEquals(2 * i + 1, reader.getFieldNumber());
|
||||
assertEquals(testSignedData[i], reader.readInt64String());
|
||||
reader.nextField();
|
||||
assertEquals(2 * i + 2, reader.getFieldNumber());
|
||||
assertEquals(testUnsignedData[i], reader.readUint64String());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests fields that use zigzag encoding.
|
||||
*/
|
||||
it('testZigzagFields', function() {
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSint32,
|
||||
jspb.BinaryWriter.prototype.writeSint32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSint64,
|
||||
jspb.BinaryWriter.prototype.writeSint64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests fields that use fixed-length encoding.
|
||||
*/
|
||||
it('testFixedFields', function() {
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readFixed32,
|
||||
jspb.BinaryWriter.prototype.writeFixed32,
|
||||
1, Math.pow(2, 32) - 1, Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readFixed64,
|
||||
jspb.BinaryWriter.prototype.writeFixed64,
|
||||
1, Math.pow(2, 64) - 1025, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSfixed32,
|
||||
jspb.BinaryWriter.prototype.writeSfixed32,
|
||||
1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSfixed64,
|
||||
jspb.BinaryWriter.prototype.writeSfixed64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests floating point fields.
|
||||
*/
|
||||
it('testFloatFields', function() {
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readFloat,
|
||||
jspb.BinaryWriter.prototype.writeFloat,
|
||||
jspb.BinaryConstants.FLOAT32_MIN,
|
||||
-jspb.BinaryConstants.FLOAT32_MAX,
|
||||
jspb.BinaryConstants.FLOAT32_MAX,
|
||||
truncate);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readDouble,
|
||||
jspb.BinaryWriter.prototype.writeDouble,
|
||||
jspb.BinaryConstants.FLOAT64_EPS * 10,
|
||||
-jspb.BinaryConstants.FLOAT64_MIN,
|
||||
jspb.BinaryConstants.FLOAT64_MIN,
|
||||
function(x) { return x; });
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests length-delimited string fields.
|
||||
*/
|
||||
it('testStringFields', function() {
|
||||
var s1 = 'The quick brown fox jumps over the lazy dog.';
|
||||
var s2 = '人人生而自由,在尊嚴和權利上一律平等。';
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
writer.writeString(1, s1);
|
||||
writer.writeString(2, s2);
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(s1, reader.readString());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
assertEquals(s2, reader.readString());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests length-delimited byte fields.
|
||||
*/
|
||||
it('testByteFields', function() {
|
||||
var message = [];
|
||||
var lowerLimit = 1;
|
||||
var upperLimit = 256;
|
||||
var scale = 1.1;
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) {
|
||||
var len = Math.round(cursor);
|
||||
var bytes = [];
|
||||
for (var i = 0; i < len; i++) bytes.push(i % 256);
|
||||
|
||||
writer.writeBytes(len, bytes);
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) {
|
||||
var len = Math.round(cursor);
|
||||
if (len != reader.getFieldNumber()) throw 'fail!';
|
||||
|
||||
var bytes = reader.readBytes();
|
||||
if (len != bytes.length) throw 'fail!';
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
if (i % 256 != bytes[i]) throw 'fail!';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests nested messages.
|
||||
*/
|
||||
it('testNesting', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
|
||||
writer.writeInt32(1, 100);
|
||||
|
||||
// Add one message with 3 int fields.
|
||||
writer.writeMessage(2, dummyMessage, function() {
|
||||
writer.writeInt32(3, 300);
|
||||
writer.writeInt32(4, 400);
|
||||
writer.writeInt32(5, 500);
|
||||
});
|
||||
|
||||
// Add one empty message.
|
||||
writer.writeMessage(6, dummyMessage, goog.nullFunction);
|
||||
|
||||
writer.writeInt32(7, 700);
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
// Validate outermost message.
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(100, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
// Validate embedded message 1.
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(300, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(4, reader.getFieldNumber());
|
||||
assertEquals(400, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(5, reader.getFieldNumber());
|
||||
assertEquals(500, reader.readInt32());
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(6, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
// Validate embedded message 2.
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(7, reader.getFieldNumber());
|
||||
assertEquals(700, reader.readInt32());
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests skipping fields of each type by interleaving them with sentinel
|
||||
* values and skipping everything that's not a sentinel.
|
||||
*/
|
||||
it('testSkipField', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var sentinel = 123456789;
|
||||
|
||||
// Write varint fields of different sizes.
|
||||
writer.writeInt32(1, sentinel);
|
||||
writer.writeInt32(1, 1);
|
||||
writer.writeInt32(1, 1000);
|
||||
writer.writeInt32(1, 1000000);
|
||||
writer.writeInt32(1, 1000000000);
|
||||
|
||||
// Write fixed 64-bit encoded fields.
|
||||
writer.writeInt32(2, sentinel);
|
||||
writer.writeDouble(2, 1);
|
||||
writer.writeFixed64(2, 1);
|
||||
writer.writeSfixed64(2, 1);
|
||||
|
||||
// Write fixed 32-bit encoded fields.
|
||||
writer.writeInt32(3, sentinel);
|
||||
writer.writeFloat(3, 1);
|
||||
writer.writeFixed32(3, 1);
|
||||
writer.writeSfixed32(3, 1);
|
||||
|
||||
// Write delimited fields.
|
||||
writer.writeInt32(4, sentinel);
|
||||
writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
writer.writeString(4, 'The quick brown fox jumps over the lazy dog');
|
||||
|
||||
// Write a group with a nested group inside.
|
||||
writer.writeInt32(5, sentinel);
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
writer.writeGroup(5, dummyMessage, function() {
|
||||
writer.writeInt64(42, 42);
|
||||
writer.writeGroup(6, dummyMessage, function() {
|
||||
writer.writeInt64(84, 42);
|
||||
});
|
||||
});
|
||||
|
||||
// Write final sentinel.
|
||||
writer.writeInt32(6, sentinel);
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
function skip(field, count) {
|
||||
for (var i = 0; i < count; i++) {
|
||||
reader.nextField();
|
||||
if (field != reader.getFieldNumber()) throw 'fail!';
|
||||
reader.skipField();
|
||||
}
|
||||
}
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(1, 4);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(2, 3);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(3, 3);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(4, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(4, 2);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(5, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(5, 1);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(6, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests packed fields.
|
||||
*/
|
||||
it('testPackedFields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var sentinel = 123456789;
|
||||
|
||||
var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10];
|
||||
var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
|
||||
var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
|
||||
var boolData = [true, false, true, true, false, false, true, false];
|
||||
|
||||
for (var i = 0; i < floatData.length; i++) {
|
||||
floatData[i] = truncate(floatData[i]);
|
||||
}
|
||||
|
||||
writer.writeInt32(1, sentinel);
|
||||
|
||||
writer.writePackedInt32(2, signedData);
|
||||
writer.writePackedInt64(2, signedData);
|
||||
writer.writePackedUint32(2, unsignedData);
|
||||
writer.writePackedUint64(2, unsignedData);
|
||||
writer.writePackedSint32(2, signedData);
|
||||
writer.writePackedSint64(2, signedData);
|
||||
writer.writePackedFixed32(2, unsignedData);
|
||||
writer.writePackedFixed64(2, unsignedData);
|
||||
writer.writePackedSfixed32(2, signedData);
|
||||
writer.writePackedSfixed64(2, signedData);
|
||||
writer.writePackedFloat(2, floatData);
|
||||
writer.writePackedDouble(2, doubleData);
|
||||
writer.writePackedBool(2, boolData);
|
||||
writer.writePackedEnum(2, unsignedData);
|
||||
|
||||
writer.writeInt32(3, sentinel);
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedInt32(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedInt64(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedUint32(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedUint64(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedSint32(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedSint64(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedFixed32(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedFixed64(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedSfixed32(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedSfixed64(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedFloat(), floatData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedDouble(), doubleData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedBool(), boolData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedEnum(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Byte blobs inside nested messages should always have their byte offset set
|
||||
* relative to the start of the outermost blob, not the start of their parent
|
||||
* blob.
|
||||
*/
|
||||
it('testNestedBlobs', function() {
|
||||
// Create a proto consisting of two nested messages, with the inner one
|
||||
// containing a blob of bytes.
|
||||
|
||||
var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
|
||||
var blob = [1, 2, 3, 4, 5];
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
|
||||
writer.writeMessage(1, dummyMessage, function() {
|
||||
writer.writeMessage(1, dummyMessage, function() {
|
||||
writer.writeBytes(1, blob);
|
||||
});
|
||||
});
|
||||
|
||||
// Peel off the outer two message layers. Each layer should have two bytes
|
||||
// of overhead, one for the field tag and one for the length of the inner
|
||||
// blob.
|
||||
|
||||
var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer());
|
||||
assertEquals(fieldTag, decoder1.readUnsignedVarint32());
|
||||
assertEquals(blob.length + 4, decoder1.readUnsignedVarint32());
|
||||
|
||||
var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4));
|
||||
assertEquals(fieldTag, decoder2.readUnsignedVarint32());
|
||||
assertEquals(blob.length + 2, decoder2.readUnsignedVarint32());
|
||||
|
||||
assertEquals(fieldTag, decoder2.readUnsignedVarint32());
|
||||
assertEquals(blob.length, decoder2.readUnsignedVarint32());
|
||||
var bytes = decoder2.readBytes(blob.length);
|
||||
|
||||
assertElementsEquals(bytes, blob);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests read callbacks.
|
||||
*/
|
||||
it('testReadCallbacks', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
|
||||
// Add an int, a submessage, and another int.
|
||||
writer.writeInt32(1, 100);
|
||||
|
||||
writer.writeMessage(2, dummyMessage, function() {
|
||||
writer.writeInt32(3, 300);
|
||||
writer.writeInt32(4, 400);
|
||||
writer.writeInt32(5, 500);
|
||||
});
|
||||
|
||||
writer.writeInt32(7, 700);
|
||||
|
||||
// Create the reader and register a custom read callback.
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
/**
|
||||
* @param {!jspb.BinaryReader} reader
|
||||
* @return {*}
|
||||
*/
|
||||
function readCallback(reader) {
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(300, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(4, reader.getFieldNumber());
|
||||
assertEquals(400, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(5, reader.getFieldNumber());
|
||||
assertEquals(500, reader.readInt32());
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
};
|
||||
|
||||
reader.registerReadCallback('readCallback', readCallback);
|
||||
|
||||
// Read the container message.
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(100, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
// Decode the embedded message using the registered callback.
|
||||
reader.runReadCallback('readCallback');
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(7, reader.getFieldNumber());
|
||||
assertEquals(700, reader.readInt32());
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
});
|
||||
});
|
668
js/compatibility_tests/v3.1.0/binary/utils_test.js
Normal file
668
js/compatibility_tests/v3.1.0/binary/utils_test.js
Normal file
@ -0,0 +1,668 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/**
|
||||
* @fileoverview Test cases for jspb's helper functions.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
goog.require('jspb.utils');
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @return {number}
|
||||
*/
|
||||
function truncate(x) {
|
||||
var temp = new Float32Array(1);
|
||||
temp[0] = x;
|
||||
return temp[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an 64-bit integer in split representation to a 64-bit hash string
|
||||
* (8 bits encoded per character).
|
||||
* @param {number} bitsLow The low 32 bits of the split 64-bit integer.
|
||||
* @param {number} bitsHigh The high 32 bits of the split 64-bit integer.
|
||||
* @return {string} The encoded hash string, 8 bits per character.
|
||||
*/
|
||||
function toHashString(bitsLow, bitsHigh) {
|
||||
return String.fromCharCode((bitsLow >>> 0) & 0xFF,
|
||||
(bitsLow >>> 8) & 0xFF,
|
||||
(bitsLow >>> 16) & 0xFF,
|
||||
(bitsLow >>> 24) & 0xFF,
|
||||
(bitsHigh >>> 0) & 0xFF,
|
||||
(bitsHigh >>> 8) & 0xFF,
|
||||
(bitsHigh >>> 16) & 0xFF,
|
||||
(bitsHigh >>> 24) & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
describe('binaryUtilsTest', function() {
|
||||
/**
|
||||
* Tests lossless binary-to-decimal conversion.
|
||||
*/
|
||||
it('testDecimalConversion', function() {
|
||||
// Check some magic numbers.
|
||||
var result =
|
||||
jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304);
|
||||
assertEquals('10000000000000000001', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b);
|
||||
assertEquals('123456789123456789', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c);
|
||||
assertEquals('12345678901234567890', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8);
|
||||
assertEquals('9876543210987654321', result);
|
||||
|
||||
// Check limits.
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000);
|
||||
assertEquals('0', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF);
|
||||
assertEquals('18446744073709551615', result);
|
||||
|
||||
// Check each bit of the low dword.
|
||||
for (var i = 0; i < 32; i++) {
|
||||
var low = (1 << i) >>> 0;
|
||||
result = jspb.utils.joinUnsignedDecimalString(low, 0);
|
||||
assertEquals('' + Math.pow(2, i), result);
|
||||
}
|
||||
|
||||
// Check the first 20 bits of the high dword.
|
||||
for (var i = 0; i < 20; i++) {
|
||||
var high = (1 << i) >>> 0;
|
||||
result = jspb.utils.joinUnsignedDecimalString(0, high);
|
||||
assertEquals('' + Math.pow(2, 32 + i), result);
|
||||
}
|
||||
|
||||
// V8's internal double-to-string conversion is inaccurate for values above
|
||||
// 2^52, even if they're representable integers - check the rest of the bits
|
||||
// manually against the correct string representations of 2^N.
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000);
|
||||
assertEquals('4503599627370496', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000);
|
||||
assertEquals('9007199254740992', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000);
|
||||
assertEquals('18014398509481984', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000);
|
||||
assertEquals('36028797018963968', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000);
|
||||
assertEquals('72057594037927936', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000);
|
||||
assertEquals('144115188075855872', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000);
|
||||
assertEquals('288230376151711744', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000);
|
||||
assertEquals('576460752303423488', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000);
|
||||
assertEquals('1152921504606846976', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000);
|
||||
assertEquals('2305843009213693952', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000);
|
||||
assertEquals('4611686018427387904', result);
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000);
|
||||
assertEquals('9223372036854775808', result);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Going from hash strings to decimal strings should also be lossless.
|
||||
*/
|
||||
it('testHashToDecimalConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.hash64ToDecimalString;
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x00000000), false);
|
||||
assertEquals('0', result);
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x00000000), true);
|
||||
assertEquals('0', result);
|
||||
|
||||
result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false);
|
||||
assertEquals('18446744073709551615', result);
|
||||
|
||||
result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true);
|
||||
assertEquals('-1', result);
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x80000000), false);
|
||||
assertEquals('9223372036854775808', result);
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x80000000), true);
|
||||
assertEquals('-9223372036854775808', result);
|
||||
|
||||
result = convert(toHashString(0xacd05f15, 0x01b69b4b), false);
|
||||
assertEquals('123456789123456789', result);
|
||||
|
||||
result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true);
|
||||
assertEquals('-123456789123456789', result);
|
||||
|
||||
// And converting arrays of hashes should work the same way.
|
||||
result = jspb.utils.hash64ArrayToDecimalStrings([
|
||||
toHashString(0xFFFFFFFF, 0xFFFFFFFF),
|
||||
toHashString(0x00000000, 0x80000000),
|
||||
toHashString(0xacd05f15, 0x01b69b4b)], false);
|
||||
assertEquals(3, result.length);
|
||||
assertEquals('18446744073709551615', result[0]);
|
||||
assertEquals('9223372036854775808', result[1]);
|
||||
assertEquals('123456789123456789', result[2]);
|
||||
});
|
||||
|
||||
/*
|
||||
* Going from decimal strings to hash strings should be lossless.
|
||||
*/
|
||||
it('testDecimalToHashConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.decimalStringToHash64;
|
||||
|
||||
result = convert('0');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);
|
||||
|
||||
result = convert('-1');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
|
||||
|
||||
result = convert('18446744073709551615');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
|
||||
|
||||
result = convert('9223372036854775808');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result);
|
||||
|
||||
result = convert('-9223372036854775808');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]), result);
|
||||
|
||||
result = convert('123456789123456789');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]), result);
|
||||
|
||||
result = convert('-123456789123456789');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]), result);
|
||||
});
|
||||
|
||||
/**
|
||||
* Going from hash strings to hex strings should be lossless.
|
||||
*/
|
||||
it('testHashToHexConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.hash64ToHexString;
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x00000000));
|
||||
assertEquals('0x0000000000000000', result);
|
||||
|
||||
result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF));
|
||||
assertEquals('0xffffffffffffffff', result);
|
||||
|
||||
result = convert(toHashString(0x12345678, 0x9ABCDEF0));
|
||||
assertEquals('0x9abcdef012345678', result);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Going from hex strings to hash strings should be lossless.
|
||||
*/
|
||||
it('testHexToHashConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.hexStringToHash64;
|
||||
|
||||
result = convert('0x0000000000000000');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]), result);
|
||||
|
||||
result = convert('0xffffffffffffffff');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]), result);
|
||||
|
||||
// Hex string is big-endian, hash string is little-endian.
|
||||
result = convert('0x123456789ABCDEF0');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]), result);
|
||||
|
||||
// Capitalization should not matter.
|
||||
result = convert('0x0000abcdefABCDEF');
|
||||
assertEquals(String.fromCharCode.apply(null,
|
||||
[0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]), result);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Going from numbers to hash strings should be lossless for up to 53 bits of
|
||||
* precision.
|
||||
*/
|
||||
it('testNumberToHashConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.numberToHash64;
|
||||
|
||||
result = convert(0x0000000000000);
|
||||
assertEquals('0x0000000000000000', jspb.utils.hash64ToHexString(result));
|
||||
|
||||
result = convert(0xFFFFFFFFFFFFF);
|
||||
assertEquals('0x000fffffffffffff', jspb.utils.hash64ToHexString(result));
|
||||
|
||||
result = convert(0x123456789ABCD);
|
||||
assertEquals('0x000123456789abcd', jspb.utils.hash64ToHexString(result));
|
||||
|
||||
result = convert(0xDCBA987654321);
|
||||
assertEquals('0x000dcba987654321', jspb.utils.hash64ToHexString(result));
|
||||
|
||||
// 53 bits of precision should not be truncated.
|
||||
result = convert(0x10000000000001);
|
||||
assertEquals('0x0010000000000001', jspb.utils.hash64ToHexString(result));
|
||||
|
||||
// 54 bits of precision should be truncated.
|
||||
result = convert(0x20000000000001);
|
||||
assertNotEquals(
|
||||
'0x0020000000000001', jspb.utils.hash64ToHexString(result));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Sanity check the behavior of Javascript's strings when doing funny things
|
||||
* with unicode characters.
|
||||
*/
|
||||
it('sanityCheckUnicodeStrings', function() {
|
||||
var strings = new Array(65536);
|
||||
|
||||
// All possible unsigned 16-bit values should be storable in a string, they
|
||||
// shouldn't do weird things with the length of the string, and they should
|
||||
// come back out of the string unchanged.
|
||||
for (var i = 0; i < 65536; i++) {
|
||||
strings[i] = 'a' + String.fromCharCode(i) + 'a';
|
||||
if (3 != strings[i].length) throw 'fail!';
|
||||
if (i != strings[i].charCodeAt(1)) throw 'fail!';
|
||||
}
|
||||
|
||||
// Each unicode character should compare equal to itself and not equal to a
|
||||
// different unicode character.
|
||||
for (var i = 0; i < 65536; i++) {
|
||||
if (strings[i] != strings[i]) throw 'fail!';
|
||||
if (strings[i] == strings[(i + 1) % 65536]) throw 'fail!';
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests conversion from 32-bit floating point numbers to split64 numbers.
|
||||
*/
|
||||
it('testFloat32ToSplit64', function() {
|
||||
var f32_eps = jspb.BinaryConstants.FLOAT32_EPS;
|
||||
var f32_min = jspb.BinaryConstants.FLOAT32_MIN;
|
||||
var f32_max = jspb.BinaryConstants.FLOAT32_MAX;
|
||||
|
||||
// NaN.
|
||||
jspb.utils.splitFloat32(NaN);
|
||||
if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low,
|
||||
jspb.utils.split64High))) {
|
||||
throw 'fail!';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number=} opt_bits
|
||||
*/
|
||||
function test(x, opt_bits) {
|
||||
jspb.utils.splitFloat32(x);
|
||||
if (goog.isDef(opt_bits)) {
|
||||
if (opt_bits != jspb.utils.split64Low) throw 'fail!';
|
||||
}
|
||||
if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low,
|
||||
jspb.utils.split64High)) {
|
||||
throw 'fail!';
|
||||
}
|
||||
}
|
||||
|
||||
// Positive and negative infinity.
|
||||
test(Infinity, 0x7f800000);
|
||||
test(-Infinity, 0xff800000);
|
||||
|
||||
// Positive and negative zero.
|
||||
test(0, 0x00000000);
|
||||
test(-0, 0x80000000);
|
||||
|
||||
// Positive and negative epsilon.
|
||||
test(f32_eps, 0x00000001);
|
||||
test(-f32_eps, 0x80000001);
|
||||
|
||||
// Positive and negative min.
|
||||
test(f32_min, 0x00800000);
|
||||
test(-f32_min, 0x80800000);
|
||||
|
||||
// Positive and negative max.
|
||||
test(f32_max, 0x7F7FFFFF);
|
||||
test(-f32_max, 0xFF7FFFFF);
|
||||
|
||||
// Various positive values.
|
||||
var cursor = f32_eps * 10;
|
||||
while (cursor != Infinity) {
|
||||
test(cursor);
|
||||
cursor *= 1.1;
|
||||
}
|
||||
|
||||
// Various negative values.
|
||||
cursor = -f32_eps * 10;
|
||||
while (cursor != -Infinity) {
|
||||
test(cursor);
|
||||
cursor *= 1.1;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests conversion from 64-bit floating point numbers to split64 numbers.
|
||||
*/
|
||||
it('testFloat64ToSplit64', function() {
|
||||
var f64_eps = jspb.BinaryConstants.FLOAT64_EPS;
|
||||
var f64_min = jspb.BinaryConstants.FLOAT64_MIN;
|
||||
var f64_max = jspb.BinaryConstants.FLOAT64_MAX;
|
||||
|
||||
// NaN.
|
||||
jspb.utils.splitFloat64(NaN);
|
||||
if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low,
|
||||
jspb.utils.split64High))) {
|
||||
throw 'fail!';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number=} opt_highBits
|
||||
* @param {number=} opt_lowBits
|
||||
*/
|
||||
function test(x, opt_highBits, opt_lowBits) {
|
||||
jspb.utils.splitFloat64(x);
|
||||
if (goog.isDef(opt_highBits)) {
|
||||
if (opt_highBits != jspb.utils.split64High) throw 'fail!';
|
||||
}
|
||||
if (goog.isDef(opt_lowBits)) {
|
||||
if (opt_lowBits != jspb.utils.split64Low) throw 'fail!';
|
||||
}
|
||||
if (x != jspb.utils.joinFloat64(jspb.utils.split64Low,
|
||||
jspb.utils.split64High)) {
|
||||
throw 'fail!';
|
||||
}
|
||||
}
|
||||
|
||||
// Positive and negative infinity.
|
||||
test(Infinity, 0x7ff00000, 0x00000000);
|
||||
test(-Infinity, 0xfff00000, 0x00000000);
|
||||
|
||||
// Positive and negative zero.
|
||||
test(0, 0x00000000, 0x00000000);
|
||||
test(-0, 0x80000000, 0x00000000);
|
||||
|
||||
// Positive and negative epsilon.
|
||||
test(f64_eps, 0x00000000, 0x00000001);
|
||||
test(-f64_eps, 0x80000000, 0x00000001);
|
||||
|
||||
// Positive and negative min.
|
||||
test(f64_min, 0x00100000, 0x00000000);
|
||||
test(-f64_min, 0x80100000, 0x00000000);
|
||||
|
||||
// Positive and negative max.
|
||||
test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF);
|
||||
test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF);
|
||||
|
||||
// Various positive values.
|
||||
var cursor = f64_eps * 10;
|
||||
while (cursor != Infinity) {
|
||||
test(cursor);
|
||||
cursor *= 1.1;
|
||||
}
|
||||
|
||||
// Various negative values.
|
||||
cursor = -f64_eps * 10;
|
||||
while (cursor != -Infinity) {
|
||||
test(cursor);
|
||||
cursor *= 1.1;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting packed varints.
|
||||
*/
|
||||
it('testCountVarints', function() {
|
||||
var values = [];
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
values.push(Math.floor(i));
|
||||
}
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writePackedUint64(1, values);
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
|
||||
// We should have two more varints than we started with - one for the field
|
||||
// tag, one for the packed length.
|
||||
assertEquals(values.length + 2,
|
||||
jspb.utils.countVarints(buffer, 0, buffer.length));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting matching varint fields.
|
||||
*/
|
||||
it('testCountVarintFields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeUint64(1, Math.floor(i));
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
assertEquals(count,
|
||||
jspb.utils.countVarintFields(buffer, 0, buffer.length, 1));
|
||||
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeUint64(123456789, Math.floor(i));
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
buffer = new Uint8Array(writer.getResultBuffer());
|
||||
assertEquals(count,
|
||||
jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting matching fixed32 fields.
|
||||
*/
|
||||
it('testCountFixed32Fields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeFixed32(1, Math.floor(i));
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
assertEquals(count,
|
||||
jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1));
|
||||
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeFixed32(123456789, Math.floor(i));
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
buffer = new Uint8Array(writer.getResultBuffer());
|
||||
assertEquals(count,
|
||||
jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting matching fixed64 fields.
|
||||
*/
|
||||
it('testCountFixed64Fields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeDouble(1, i);
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
assertEquals(count,
|
||||
jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1));
|
||||
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeDouble(123456789, i);
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
buffer = new Uint8Array(writer.getResultBuffer());
|
||||
assertEquals(count,
|
||||
jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting matching delimited fields.
|
||||
*/
|
||||
it('testCountDelimitedFields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var count = 0;
|
||||
for (var i = 1; i < 1000; i *= 1.1) {
|
||||
writer.writeBytes(1, [Math.floor(i)]);
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
assertEquals(count,
|
||||
jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1));
|
||||
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
count = 0;
|
||||
for (var i = 1; i < 1000; i *= 1.1) {
|
||||
writer.writeBytes(123456789, [Math.floor(i)]);
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
buffer = new Uint8Array(writer.getResultBuffer());
|
||||
assertEquals(count,
|
||||
jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests byte format for debug strings.
|
||||
*/
|
||||
it('testDebugBytesToTextFormat', function() {
|
||||
assertEquals('""', jspb.utils.debugBytesToTextFormat(null));
|
||||
assertEquals('"\\x00\\x10\\xff"',
|
||||
jspb.utils.debugBytesToTextFormat([0, 16, 255]));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests converting byte blob sources into byte blobs.
|
||||
*/
|
||||
it('testByteSourceToUint8Array', function() {
|
||||
var convert = jspb.utils.byteSourceToUint8Array;
|
||||
|
||||
var sourceData = [];
|
||||
for (var i = 0; i < 256; i++) {
|
||||
sourceData.push(i);
|
||||
}
|
||||
|
||||
var sourceBytes = new Uint8Array(sourceData);
|
||||
var sourceBuffer = sourceBytes.buffer;
|
||||
var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData);
|
||||
var sourceString = String.fromCharCode.apply(null, sourceData);
|
||||
|
||||
function check(result) {
|
||||
assertEquals(Uint8Array, result.constructor);
|
||||
assertEquals(sourceData.length, result.length);
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
assertEquals(sourceData[i], result[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Converting Uint8Arrays into Uint8Arrays should be a no-op.
|
||||
assertEquals(sourceBytes, convert(sourceBytes));
|
||||
|
||||
// Converting Array.<numbers> into Uint8Arrays should work.
|
||||
check(convert(sourceData));
|
||||
|
||||
// Converting ArrayBuffers into Uint8Arrays should work.
|
||||
check(convert(sourceBuffer));
|
||||
|
||||
// Converting base64-encoded strings into Uint8Arrays should work.
|
||||
check(convert(sourceBase64));
|
||||
});
|
||||
});
|
122
js/compatibility_tests/v3.1.0/binary/writer_test.js
Normal file
122
js/compatibility_tests/v3.1.0/binary/writer_test.js
Normal file
@ -0,0 +1,122 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/**
|
||||
* @fileoverview Test cases for jspb's binary protocol buffer writer. In
|
||||
* practice BinaryWriter is used to drive the Decoder and Reader test cases,
|
||||
* so only writer-specific tests are here.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.require('goog.crypt');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
|
||||
|
||||
/**
|
||||
* @param {function()} func This function should throw an error when run.
|
||||
*/
|
||||
function assertFails(func) {
|
||||
var e = assertThrows(func);
|
||||
//assertNotNull(e.toString().match(/Error/));
|
||||
}
|
||||
|
||||
|
||||
describe('binaryWriterTest', function() {
|
||||
/**
|
||||
* Verifies that misuse of the writer class triggers assertions.
|
||||
*/
|
||||
it('testWriteErrors', function() {
|
||||
// Submessages with invalid field indices should assert.
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeMessage(-1, dummyMessage, goog.nullFunction);
|
||||
});
|
||||
|
||||
// Writing invalid field indices should assert.
|
||||
writer = new jspb.BinaryWriter();
|
||||
assertFails(function() {writer.writeUint64(-1, 1);});
|
||||
|
||||
// Writing out-of-range field values should assert.
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
assertFails(function() {writer.writeInt32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeInt32(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeInt64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeInt64(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeUint32(1, -1);});
|
||||
assertFails(function() {writer.writeUint32(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeUint64(1, -1);});
|
||||
assertFails(function() {writer.writeUint64(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeSint32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSint32(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeSint64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSint64(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeFixed32(1, -1);});
|
||||
assertFails(function() {writer.writeFixed32(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeFixed64(1, -1);});
|
||||
assertFails(function() {writer.writeFixed64(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeSfixed32(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSfixed32(1, Infinity);});
|
||||
|
||||
assertFails(function() {writer.writeSfixed64(1, -Infinity);});
|
||||
assertFails(function() {writer.writeSfixed64(1, Infinity);});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Basic test of retrieving the result as a Uint8Array buffer
|
||||
*/
|
||||
it('testGetResultBuffer', function() {
|
||||
var expected = '0864120b48656c6c6f20776f726c641a0301020320c801';
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writeUint32(1, 100);
|
||||
writer.writeString(2, 'Hello world');
|
||||
writer.writeBytes(3, new Uint8Array([1, 2, 3]));
|
||||
writer.writeUint32(4, 200);
|
||||
|
||||
var buffer = writer.getResultBuffer();
|
||||
assertEquals(expected, goog.crypt.byteArrayToHex(buffer));
|
||||
});
|
||||
});
|
40
js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto
Normal file
40
js/compatibility_tests/v3.1.0/commonjs/test6/test6.proto
Normal file
@ -0,0 +1,40 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "com.google.apps.jspb.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
package jspb.test.importing;
|
||||
|
||||
message ImportedMessage {
|
||||
string string_value = 1;
|
||||
}
|
42
js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto
Normal file
42
js/compatibility_tests/v3.1.0/commonjs/test7/test7.proto
Normal file
@ -0,0 +1,42 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2016 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
option java_package = "com.google.apps.jspb.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
package jspb.test.framing;
|
||||
|
||||
import "test6/test6.proto";
|
||||
|
||||
message FramingMessage {
|
||||
jspb.test.importing.ImportedMessage imported_message = 1;
|
||||
}
|
51
js/compatibility_tests/v3.1.0/data.proto
Normal file
51
js/compatibility_tests/v3.1.0/data.proto
Normal file
@ -0,0 +1,51 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: mwr@google.com (Mark Rawling)
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
option java_package = "com.google.apps.jspb.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
package jspb.test;
|
||||
|
||||
// legacy data, must be nested
|
||||
message data {
|
||||
message NestedData {
|
||||
required string str = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// new data, does not require nesting
|
||||
message UnnestedData {
|
||||
required string str = 1;
|
||||
}
|
||||
|
105
js/compatibility_tests/v3.1.0/debug_test.js
Normal file
105
js/compatibility_tests/v3.1.0/debug_test.js
Normal file
@ -0,0 +1,105 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
goog.require('goog.testing.asserts');
|
||||
|
||||
// CommonJS-LoadFromFile: google-protobuf
|
||||
goog.require('jspb.debug');
|
||||
|
||||
// CommonJS-LoadFromFile: test_pb
|
||||
goog.require('proto.jspb.test.HasExtensions');
|
||||
goog.require('proto.jspb.test.IsExtension');
|
||||
goog.require('proto.jspb.test.Simple1');
|
||||
|
||||
|
||||
|
||||
describe('debugTest', function() {
|
||||
it('testSimple1', function() {
|
||||
if (COMPILED) {
|
||||
return;
|
||||
}
|
||||
var message = new proto.jspb.test.Simple1();
|
||||
message.setAString('foo');
|
||||
assertObjectEquals({
|
||||
$name: 'proto.jspb.test.Simple1',
|
||||
'aString': 'foo',
|
||||
'aRepeatedStringList': []
|
||||
}, jspb.debug.dump(message));
|
||||
|
||||
message.setABoolean(true);
|
||||
message.setARepeatedStringList(['1', '2']);
|
||||
|
||||
assertObjectEquals({
|
||||
$name: 'proto.jspb.test.Simple1',
|
||||
'aString': 'foo',
|
||||
'aRepeatedStringList': ['1', '2'],
|
||||
'aBoolean': true
|
||||
}, jspb.debug.dump(message));
|
||||
|
||||
message.clearAString();
|
||||
|
||||
assertObjectEquals({
|
||||
$name: 'proto.jspb.test.Simple1',
|
||||
'aRepeatedStringList': ['1', '2'],
|
||||
'aBoolean': true
|
||||
}, jspb.debug.dump(message));
|
||||
});
|
||||
|
||||
|
||||
it('testExtensions', function() {
|
||||
if (COMPILED) {
|
||||
return;
|
||||
}
|
||||
var extension = new proto.jspb.test.IsExtension();
|
||||
extension.setExt1('ext1field');
|
||||
var extendable = new proto.jspb.test.HasExtensions();
|
||||
extendable.setStr1('v1');
|
||||
extendable.setStr2('v2');
|
||||
extendable.setStr3('v3');
|
||||
extendable.setExtension(proto.jspb.test.IsExtension.extField, extension);
|
||||
|
||||
assertObjectEquals({
|
||||
'$name': 'proto.jspb.test.HasExtensions',
|
||||
'str1': 'v1',
|
||||
'str2': 'v2',
|
||||
'str3': 'v3',
|
||||
'$extensions': {
|
||||
'extField': {
|
||||
'$name': 'proto.jspb.test.IsExtension',
|
||||
'ext1': 'ext1field'
|
||||
},
|
||||
'repeatedSimpleList': []
|
||||
}
|
||||
}, jspb.debug.dump(extendable));
|
||||
});
|
||||
|
||||
});
|
301
js/compatibility_tests/v3.1.0/maps_test.js
Normal file
301
js/compatibility_tests/v3.1.0/maps_test.js
Normal file
@ -0,0 +1,301 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.MapValueEnum');
|
||||
goog.require('proto.jspb.test.MapValueMessage');
|
||||
goog.require('proto.jspb.test.TestMapFields');
|
||||
|
||||
// CommonJS-LoadFromFile: test_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.MapValueMessageNoBinary');
|
||||
goog.require('proto.jspb.test.TestMapFieldsNoBinary');
|
||||
|
||||
/**
|
||||
* Helper: check that the given map has exactly this set of (sorted) entries.
|
||||
* @param {!jspb.Map} map
|
||||
* @param {!Array<!Array<?>>} entries
|
||||
*/
|
||||
function checkMapEquals(map, entries) {
|
||||
var arr = map.toArray();
|
||||
assertEquals(arr.length, entries.length);
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
assertElementsEquals(arr[i], entries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an ES6 iterator to an array.
|
||||
* @template T
|
||||
* @param {!Iterator<T>} iter an iterator
|
||||
* @return {!Array<T>}
|
||||
*/
|
||||
function toArray(iter) {
|
||||
var arr = [];
|
||||
while (true) {
|
||||
var val = iter.next();
|
||||
if (val.done) {
|
||||
break;
|
||||
}
|
||||
arr.push(val.value);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper: generate test methods for this TestMapFields class.
|
||||
* @param {?} msgInfo
|
||||
* @param {?} submessageCtor
|
||||
* @param {!string} suffix
|
||||
*/
|
||||
function makeTests(msgInfo, submessageCtor, suffix) {
|
||||
/**
|
||||
* Helper: fill all maps on a TestMapFields.
|
||||
* @param {?} msg
|
||||
*/
|
||||
var fillMapFields = function(msg) {
|
||||
msg.getMapStringStringMap().set('asdf', 'jkl;').set('key 2', 'hello world');
|
||||
msg.getMapStringInt32Map().set('a', 1).set('b', -2);
|
||||
msg.getMapStringInt64Map().set('c', 0x100000000).set('d', 0x200000000);
|
||||
msg.getMapStringBoolMap().set('e', true).set('f', false);
|
||||
msg.getMapStringDoubleMap().set('g', 3.14159).set('h', 2.71828);
|
||||
msg.getMapStringEnumMap()
|
||||
.set('i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR)
|
||||
.set('j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ);
|
||||
msg.getMapStringMsgMap()
|
||||
.set('k', new submessageCtor())
|
||||
.set('l', new submessageCtor());
|
||||
msg.getMapStringMsgMap().get('k').setFoo(42);
|
||||
msg.getMapStringMsgMap().get('l').setFoo(84);
|
||||
msg.getMapInt32StringMap().set(-1, 'a').set(42, 'b');
|
||||
msg.getMapInt64StringMap().set(0x123456789abc, 'c').set(0xcba987654321, 'd');
|
||||
msg.getMapBoolStringMap().set(false, 'e').set(true, 'f');
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper: check all maps on a TestMapFields.
|
||||
* @param {?} msg
|
||||
*/
|
||||
var checkMapFields = function(msg) {
|
||||
checkMapEquals(msg.getMapStringStringMap(), [
|
||||
['asdf', 'jkl;'],
|
||||
['key 2', 'hello world']
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringInt32Map(), [
|
||||
['a', 1],
|
||||
['b', -2]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringInt64Map(), [
|
||||
['c', 0x100000000],
|
||||
['d', 0x200000000]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringBoolMap(), [
|
||||
['e', true],
|
||||
['f', false]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringDoubleMap(), [
|
||||
['g', 3.14159],
|
||||
['h', 2.71828]
|
||||
]);
|
||||
checkMapEquals(msg.getMapStringEnumMap(), [
|
||||
['i', proto.jspb.test.MapValueEnum.MAP_VALUE_BAR],
|
||||
['j', proto.jspb.test.MapValueEnum.MAP_VALUE_BAZ]
|
||||
]);
|
||||
checkMapEquals(msg.getMapInt32StringMap(), [
|
||||
[-1, 'a'],
|
||||
[42, 'b']
|
||||
]);
|
||||
checkMapEquals(msg.getMapInt64StringMap(), [
|
||||
[0x123456789abc, 'c'],
|
||||
[0xcba987654321, 'd']
|
||||
]);
|
||||
checkMapEquals(msg.getMapBoolStringMap(), [
|
||||
[false, 'e'],
|
||||
[true, 'f']
|
||||
]);
|
||||
|
||||
assertEquals(msg.getMapStringMsgMap().getLength(), 2);
|
||||
assertEquals(msg.getMapStringMsgMap().get('k').getFoo(), 42);
|
||||
assertEquals(msg.getMapStringMsgMap().get('l').getFoo(), 84);
|
||||
|
||||
var entries = toArray(msg.getMapStringMsgMap().entries());
|
||||
assertEquals(entries.length, 2);
|
||||
entries.forEach(function(entry) {
|
||||
var key = entry[0];
|
||||
var val = entry[1];
|
||||
assert(val === msg.getMapStringMsgMap().get(key));
|
||||
});
|
||||
|
||||
msg.getMapStringMsgMap().forEach(function(val, key) {
|
||||
assert(val === msg.getMapStringMsgMap().get(key));
|
||||
});
|
||||
};
|
||||
|
||||
it('testMapStringStringField' + suffix, function() {
|
||||
var msg = new msgInfo.constructor();
|
||||
assertEquals(msg.getMapStringStringMap().getLength(), 0);
|
||||
assertEquals(msg.getMapStringInt32Map().getLength(), 0);
|
||||
assertEquals(msg.getMapStringInt64Map().getLength(), 0);
|
||||
assertEquals(msg.getMapStringBoolMap().getLength(), 0);
|
||||
assertEquals(msg.getMapStringDoubleMap().getLength(), 0);
|
||||
assertEquals(msg.getMapStringEnumMap().getLength(), 0);
|
||||
assertEquals(msg.getMapStringMsgMap().getLength(), 0);
|
||||
|
||||
// Re-create to clear out any internally-cached wrappers, etc.
|
||||
msg = new msgInfo.constructor();
|
||||
var m = msg.getMapStringStringMap();
|
||||
assertEquals(m.has('asdf'), false);
|
||||
assertEquals(m.get('asdf'), undefined);
|
||||
m.set('asdf', 'hello world');
|
||||
assertEquals(m.has('asdf'), true);
|
||||
assertEquals(m.get('asdf'), 'hello world');
|
||||
m.set('jkl;', 'key 2');
|
||||
assertEquals(m.has('jkl;'), true);
|
||||
assertEquals(m.get('jkl;'), 'key 2');
|
||||
assertEquals(m.getLength(), 2);
|
||||
var it = m.entries();
|
||||
assertElementsEquals(it.next().value, ['asdf', 'hello world']);
|
||||
assertElementsEquals(it.next().value, ['jkl;', 'key 2']);
|
||||
assertEquals(it.next().done, true);
|
||||
checkMapEquals(m, [
|
||||
['asdf', 'hello world'],
|
||||
['jkl;', 'key 2']
|
||||
]);
|
||||
m.del('jkl;');
|
||||
assertEquals(m.has('jkl;'), false);
|
||||
assertEquals(m.get('jkl;'), undefined);
|
||||
assertEquals(m.getLength(), 1);
|
||||
it = m.keys();
|
||||
assertEquals(it.next().value, 'asdf');
|
||||
assertEquals(it.next().done, true);
|
||||
it = m.values();
|
||||
assertEquals(it.next().value, 'hello world');
|
||||
assertEquals(it.next().done, true);
|
||||
|
||||
var count = 0;
|
||||
m.forEach(function(value, key, map) {
|
||||
assertEquals(map, m);
|
||||
assertEquals(key, 'asdf');
|
||||
assertEquals(value, 'hello world');
|
||||
count++;
|
||||
});
|
||||
assertEquals(count, 1);
|
||||
|
||||
m.clear();
|
||||
assertEquals(m.getLength(), 0);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests operations on maps with all key and value types.
|
||||
*/
|
||||
it('testAllMapTypes' + suffix, function() {
|
||||
var msg = new msgInfo.constructor();
|
||||
fillMapFields(msg);
|
||||
checkMapFields(msg);
|
||||
});
|
||||
|
||||
|
||||
if (msgInfo.deserializeBinary) {
|
||||
/**
|
||||
* Tests serialization and deserialization in binary format.
|
||||
*/
|
||||
it('testBinaryFormat' + suffix, function() {
|
||||
if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(10)) {
|
||||
// IE8/9 currently doesn't support binary format because they lack
|
||||
// TypedArray.
|
||||
return;
|
||||
}
|
||||
|
||||
// Check that the format is correct.
|
||||
var msg = new msgInfo.constructor();
|
||||
msg.getMapStringStringMap().set('A', 'a');
|
||||
var serialized = msg.serializeBinary();
|
||||
var expectedSerialized = [
|
||||
0x0a, 0x6, // field 1 (map_string_string), delimited, length 6
|
||||
0x0a, 0x1, // field 1 in submessage (key), delimited, length 1
|
||||
0x41, // ASCII 'A'
|
||||
0x12, 0x1, // field 2 in submessage (value), delimited, length 1
|
||||
0x61 // ASCII 'a'
|
||||
];
|
||||
assertEquals(serialized.length, expectedSerialized.length);
|
||||
for (var i = 0; i < serialized.length; i++) {
|
||||
assertEquals(serialized[i], expectedSerialized[i]);
|
||||
}
|
||||
|
||||
// Check that all map fields successfully round-trip.
|
||||
msg = new msgInfo.constructor();
|
||||
fillMapFields(msg);
|
||||
serialized = msg.serializeBinary();
|
||||
var decoded = msgInfo.deserializeBinary(serialized);
|
||||
checkMapFields(decoded);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Exercises the lazy map<->underlying array sync.
|
||||
*/
|
||||
it('testLazyMapSync' + suffix, function() {
|
||||
// Start with a JSPB array containing a few map entries.
|
||||
var entries = [
|
||||
['a', 'entry 1'],
|
||||
['c', 'entry 2'],
|
||||
['b', 'entry 3']
|
||||
];
|
||||
var msg = new msgInfo.constructor([entries]);
|
||||
assertEquals(entries.length, 3);
|
||||
assertEquals(entries[0][0], 'a');
|
||||
assertEquals(entries[1][0], 'c');
|
||||
assertEquals(entries[2][0], 'b');
|
||||
msg.getMapStringStringMap().del('a');
|
||||
assertEquals(entries.length, 3); // not yet sync'd
|
||||
msg.toArray(); // force a sync
|
||||
assertEquals(entries.length, 2);
|
||||
assertEquals(entries[0][0], 'b'); // now in sorted order
|
||||
assertEquals(entries[1][0], 'c');
|
||||
|
||||
var a = msg.toArray();
|
||||
assertEquals(a[0], entries); // retains original reference
|
||||
});
|
||||
}
|
||||
|
||||
describe('mapsTest', function() {
|
||||
makeTests({
|
||||
constructor: proto.jspb.test.TestMapFields,
|
||||
deserializeBinary: proto.jspb.test.TestMapFields.deserializeBinary
|
||||
}, proto.jspb.test.MapValueMessage, "_Binary");
|
||||
makeTests({
|
||||
constructor: proto.jspb.test.TestMapFieldsNoBinary,
|
||||
deserializeBinary: null
|
||||
}, proto.jspb.test.MapValueMessageNoBinary, "_NoBinary");
|
||||
});
|
1037
js/compatibility_tests/v3.1.0/message_test.js
Normal file
1037
js/compatibility_tests/v3.1.0/message_test.js
Normal file
File diff suppressed because it is too large
Load Diff
329
js/compatibility_tests/v3.1.0/proto3_test.js
Normal file
329
js/compatibility_tests/v3.1.0/proto3_test.js
Normal file
@ -0,0 +1,329 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.require('goog.testing.asserts');
|
||||
|
||||
// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.ForeignMessage');
|
||||
|
||||
// CommonJS-LoadFromFile: proto3_test_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.Proto3Enum');
|
||||
goog.require('proto.jspb.test.TestProto3');
|
||||
|
||||
|
||||
var BYTES = new Uint8Array([1, 2, 8, 9]);
|
||||
var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
|
||||
|
||||
|
||||
/**
|
||||
* Helper: compare a bytes field to an expected value
|
||||
* @param {Uint8Array|string} arr
|
||||
* @param {Uint8Array} expected
|
||||
* @return {boolean}
|
||||
*/
|
||||
function bytesCompare(arr, expected) {
|
||||
if (goog.isString(arr)) {
|
||||
arr = goog.crypt.base64.decodeStringToUint8Array(arr);
|
||||
}
|
||||
if (arr.length != expected.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i] != expected[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
describe('proto3Test', function() {
|
||||
/**
|
||||
* Test defaults for proto3 message fields.
|
||||
*/
|
||||
it('testProto3FieldDefaults', function() {
|
||||
var msg = new proto.jspb.test.TestProto3();
|
||||
|
||||
assertEquals(msg.getOptionalInt32(), 0);
|
||||
assertEquals(msg.getOptionalInt64(), 0);
|
||||
assertEquals(msg.getOptionalUint32(), 0);
|
||||
assertEquals(msg.getOptionalUint64(), 0);
|
||||
assertEquals(msg.getOptionalSint32(), 0);
|
||||
assertEquals(msg.getOptionalSint64(), 0);
|
||||
assertEquals(msg.getOptionalFixed32(), 0);
|
||||
assertEquals(msg.getOptionalFixed64(), 0);
|
||||
assertEquals(msg.getOptionalSfixed32(), 0);
|
||||
assertEquals(msg.getOptionalSfixed64(), 0);
|
||||
assertEquals(msg.getOptionalFloat(), 0);
|
||||
assertEquals(msg.getOptionalDouble(), 0);
|
||||
assertEquals(msg.getOptionalString(), '');
|
||||
|
||||
// TODO(b/26173701): when we change bytes fields default getter to return
|
||||
// Uint8Array, we'll want to switch this assertion to match the u8 case.
|
||||
assertEquals(typeof msg.getOptionalBytes(), 'string');
|
||||
assertEquals(msg.getOptionalBytes_asU8() instanceof Uint8Array, true);
|
||||
assertEquals(typeof msg.getOptionalBytes_asB64(), 'string');
|
||||
assertEquals(msg.getOptionalBytes().length, 0);
|
||||
assertEquals(msg.getOptionalBytes_asU8().length, 0);
|
||||
assertEquals(msg.getOptionalBytes_asB64(), '');
|
||||
|
||||
assertEquals(msg.getOptionalForeignEnum(),
|
||||
proto.jspb.test.Proto3Enum.PROTO3_FOO);
|
||||
assertEquals(msg.getOptionalForeignMessage(), undefined);
|
||||
assertEquals(msg.getOptionalForeignMessage(), undefined);
|
||||
|
||||
assertEquals(msg.getRepeatedInt32List().length, 0);
|
||||
assertEquals(msg.getRepeatedInt64List().length, 0);
|
||||
assertEquals(msg.getRepeatedUint32List().length, 0);
|
||||
assertEquals(msg.getRepeatedUint64List().length, 0);
|
||||
assertEquals(msg.getRepeatedSint32List().length, 0);
|
||||
assertEquals(msg.getRepeatedSint64List().length, 0);
|
||||
assertEquals(msg.getRepeatedFixed32List().length, 0);
|
||||
assertEquals(msg.getRepeatedFixed64List().length, 0);
|
||||
assertEquals(msg.getRepeatedSfixed32List().length, 0);
|
||||
assertEquals(msg.getRepeatedSfixed64List().length, 0);
|
||||
assertEquals(msg.getRepeatedFloatList().length, 0);
|
||||
assertEquals(msg.getRepeatedDoubleList().length, 0);
|
||||
assertEquals(msg.getRepeatedStringList().length, 0);
|
||||
assertEquals(msg.getRepeatedBytesList().length, 0);
|
||||
assertEquals(msg.getRepeatedForeignEnumList().length, 0);
|
||||
assertEquals(msg.getRepeatedForeignMessageList().length, 0);
|
||||
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Test that all fields can be set and read via a serialization roundtrip.
|
||||
*/
|
||||
it('testProto3FieldSetGet', function() {
|
||||
var msg = new proto.jspb.test.TestProto3();
|
||||
|
||||
msg.setOptionalInt32(-42);
|
||||
msg.setOptionalInt64(-0x7fffffff00000000);
|
||||
msg.setOptionalUint32(0x80000000);
|
||||
msg.setOptionalUint64(0xf000000000000000);
|
||||
msg.setOptionalSint32(-100);
|
||||
msg.setOptionalSint64(-0x8000000000000000);
|
||||
msg.setOptionalFixed32(1234);
|
||||
msg.setOptionalFixed64(0x1234567800000000);
|
||||
msg.setOptionalSfixed32(-1234);
|
||||
msg.setOptionalSfixed64(-0x1234567800000000);
|
||||
msg.setOptionalFloat(1.5);
|
||||
msg.setOptionalDouble(-1.5);
|
||||
msg.setOptionalBool(true);
|
||||
msg.setOptionalString('hello world');
|
||||
msg.setOptionalBytes(BYTES);
|
||||
var submsg = new proto.jspb.test.ForeignMessage();
|
||||
submsg.setC(16);
|
||||
msg.setOptionalForeignMessage(submsg);
|
||||
msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR);
|
||||
|
||||
msg.setRepeatedInt32List([-42]);
|
||||
msg.setRepeatedInt64List([-0x7fffffff00000000]);
|
||||
msg.setRepeatedUint32List([0x80000000]);
|
||||
msg.setRepeatedUint64List([0xf000000000000000]);
|
||||
msg.setRepeatedSint32List([-100]);
|
||||
msg.setRepeatedSint64List([-0x8000000000000000]);
|
||||
msg.setRepeatedFixed32List([1234]);
|
||||
msg.setRepeatedFixed64List([0x1234567800000000]);
|
||||
msg.setRepeatedSfixed32List([-1234]);
|
||||
msg.setRepeatedSfixed64List([-0x1234567800000000]);
|
||||
msg.setRepeatedFloatList([1.5]);
|
||||
msg.setRepeatedDoubleList([-1.5]);
|
||||
msg.setRepeatedBoolList([true]);
|
||||
msg.setRepeatedStringList(['hello world']);
|
||||
msg.setRepeatedBytesList([BYTES]);
|
||||
submsg = new proto.jspb.test.ForeignMessage();
|
||||
submsg.setC(1000);
|
||||
msg.setRepeatedForeignMessageList([submsg]);
|
||||
msg.setRepeatedForeignEnumList([proto.jspb.test.Proto3Enum.PROTO3_BAR]);
|
||||
|
||||
msg.setOneofString('asdf');
|
||||
|
||||
var serialized = msg.serializeBinary();
|
||||
msg = proto.jspb.test.TestProto3.deserializeBinary(serialized);
|
||||
|
||||
assertEquals(msg.getOptionalInt32(), -42);
|
||||
assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000);
|
||||
assertEquals(msg.getOptionalUint32(), 0x80000000);
|
||||
assertEquals(msg.getOptionalUint64(), 0xf000000000000000);
|
||||
assertEquals(msg.getOptionalSint32(), -100);
|
||||
assertEquals(msg.getOptionalSint64(), -0x8000000000000000);
|
||||
assertEquals(msg.getOptionalFixed32(), 1234);
|
||||
assertEquals(msg.getOptionalFixed64(), 0x1234567800000000);
|
||||
assertEquals(msg.getOptionalSfixed32(), -1234);
|
||||
assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000);
|
||||
assertEquals(msg.getOptionalFloat(), 1.5);
|
||||
assertEquals(msg.getOptionalDouble(), -1.5);
|
||||
assertEquals(msg.getOptionalBool(), true);
|
||||
assertEquals(msg.getOptionalString(), 'hello world');
|
||||
assertEquals(true, bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
assertEquals(msg.getOptionalForeignMessage().getC(), 16);
|
||||
assertEquals(msg.getOptionalForeignEnum(),
|
||||
proto.jspb.test.Proto3Enum.PROTO3_BAR);
|
||||
|
||||
assertElementsEquals(msg.getRepeatedInt32List(), [-42]);
|
||||
assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]);
|
||||
assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]);
|
||||
assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]);
|
||||
assertElementsEquals(msg.getRepeatedSint32List(), [-100]);
|
||||
assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]);
|
||||
assertElementsEquals(msg.getRepeatedFixed32List(), [1234]);
|
||||
assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]);
|
||||
assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]);
|
||||
assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]);
|
||||
assertElementsEquals(msg.getRepeatedFloatList(), [1.5]);
|
||||
assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]);
|
||||
assertElementsEquals(msg.getRepeatedBoolList(), [true]);
|
||||
assertElementsEquals(msg.getRepeatedStringList(), ['hello world']);
|
||||
assertEquals(msg.getRepeatedBytesList().length, 1);
|
||||
assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
|
||||
assertEquals(msg.getRepeatedForeignMessageList().length, 1);
|
||||
assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
|
||||
assertElementsEquals(msg.getRepeatedForeignEnumList(),
|
||||
[proto.jspb.test.Proto3Enum.PROTO3_BAR]);
|
||||
|
||||
assertEquals(msg.getOneofString(), 'asdf');
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Test that oneofs continue to have a notion of field presence.
|
||||
*/
|
||||
it('testOneofs', function() {
|
||||
var msg = new proto.jspb.test.TestProto3();
|
||||
|
||||
assertEquals(msg.getOneofUint32(), 0);
|
||||
assertEquals(msg.getOneofForeignMessage(), undefined);
|
||||
assertEquals(msg.getOneofString(), '');
|
||||
assertEquals(msg.getOneofBytes(), '');
|
||||
assertFalse(msg.hasOneofUint32());
|
||||
assertFalse(msg.hasOneofString());
|
||||
assertFalse(msg.hasOneofBytes());
|
||||
|
||||
msg.setOneofUint32(42);
|
||||
assertEquals(msg.getOneofUint32(), 42);
|
||||
assertEquals(msg.getOneofForeignMessage(), undefined);
|
||||
assertEquals(msg.getOneofString(), '');
|
||||
assertEquals(msg.getOneofBytes(), '');
|
||||
assertTrue(msg.hasOneofUint32());
|
||||
assertFalse(msg.hasOneofString());
|
||||
assertFalse(msg.hasOneofBytes());
|
||||
|
||||
|
||||
var submsg = new proto.jspb.test.ForeignMessage();
|
||||
msg.setOneofForeignMessage(submsg);
|
||||
assertEquals(msg.getOneofUint32(), 0);
|
||||
assertEquals(msg.getOneofForeignMessage(), submsg);
|
||||
assertEquals(msg.getOneofString(), '');
|
||||
assertEquals(msg.getOneofBytes(), '');
|
||||
assertFalse(msg.hasOneofUint32());
|
||||
assertFalse(msg.hasOneofString());
|
||||
assertFalse(msg.hasOneofBytes());
|
||||
|
||||
msg.setOneofString('hello');
|
||||
assertEquals(msg.getOneofUint32(), 0);
|
||||
assertEquals(msg.getOneofForeignMessage(), undefined);
|
||||
assertEquals(msg.getOneofString(), 'hello');
|
||||
assertEquals(msg.getOneofBytes(), '');
|
||||
assertFalse(msg.hasOneofUint32());
|
||||
assertTrue(msg.hasOneofString());
|
||||
assertFalse(msg.hasOneofBytes());
|
||||
|
||||
msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
|
||||
assertEquals(msg.getOneofUint32(), 0);
|
||||
assertEquals(msg.getOneofForeignMessage(), undefined);
|
||||
assertEquals(msg.getOneofString(), '');
|
||||
assertEquals(msg.getOneofBytes_asB64(),
|
||||
goog.crypt.base64.encodeString('\u00FF\u00FF'));
|
||||
assertFalse(msg.hasOneofUint32());
|
||||
assertFalse(msg.hasOneofString());
|
||||
assertTrue(msg.hasOneofBytes());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Test that "default"-valued primitive fields are not emitted on the wire.
|
||||
*/
|
||||
it('testNoSerializeDefaults', function() {
|
||||
var msg = new proto.jspb.test.TestProto3();
|
||||
|
||||
// Set each primitive to a non-default value, then back to its default, to
|
||||
// ensure that the serialization is actually checking the value and not just
|
||||
// whether it has ever been set.
|
||||
msg.setOptionalInt32(42);
|
||||
msg.setOptionalInt32(0);
|
||||
msg.setOptionalDouble(3.14);
|
||||
msg.setOptionalDouble(0.0);
|
||||
msg.setOptionalBool(true);
|
||||
msg.setOptionalBool(false);
|
||||
msg.setOptionalString('hello world');
|
||||
msg.setOptionalString('');
|
||||
msg.setOptionalBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
|
||||
msg.setOptionalBytes('');
|
||||
msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage());
|
||||
msg.setOptionalForeignMessage(null);
|
||||
msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_BAR);
|
||||
msg.setOptionalForeignEnum(proto.jspb.test.Proto3Enum.PROTO3_FOO);
|
||||
msg.setOneofUint32(32);
|
||||
msg.clearOneofUint32();
|
||||
|
||||
|
||||
var serialized = msg.serializeBinary();
|
||||
assertEquals(0, serialized.length);
|
||||
});
|
||||
|
||||
/**
|
||||
* Test that base64 string and Uint8Array are interchangeable in bytes fields.
|
||||
*/
|
||||
it('testBytesFieldsInterop', function() {
|
||||
var msg = new proto.jspb.test.TestProto3();
|
||||
// Set as a base64 string and check all the getters work.
|
||||
msg.setOptionalBytes(BYTES_B64);
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
|
||||
// Test binary serialize round trip doesn't break it.
|
||||
msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary());
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
|
||||
msg = new proto.jspb.test.TestProto3();
|
||||
// Set as a Uint8Array and check all the getters work.
|
||||
msg.setOptionalBytes(BYTES);
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
|
||||
assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
|
||||
|
||||
});
|
||||
});
|
89
js/compatibility_tests/v3.1.0/proto3_test.proto
Normal file
89
js/compatibility_tests/v3.1.0/proto3_test.proto
Normal file
@ -0,0 +1,89 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
import "testbinary.proto";
|
||||
|
||||
package jspb.test;
|
||||
|
||||
message TestProto3 {
|
||||
int32 optional_int32 = 1;
|
||||
int64 optional_int64 = 2;
|
||||
uint32 optional_uint32 = 3;
|
||||
uint64 optional_uint64 = 4;
|
||||
sint32 optional_sint32 = 5;
|
||||
sint64 optional_sint64 = 6;
|
||||
fixed32 optional_fixed32 = 7;
|
||||
fixed64 optional_fixed64 = 8;
|
||||
sfixed32 optional_sfixed32 = 9;
|
||||
sfixed64 optional_sfixed64 = 10;
|
||||
float optional_float = 11;
|
||||
double optional_double = 12;
|
||||
bool optional_bool = 13;
|
||||
string optional_string = 14;
|
||||
bytes optional_bytes = 15;
|
||||
|
||||
ForeignMessage optional_foreign_message = 19;
|
||||
Proto3Enum optional_foreign_enum = 22;
|
||||
|
||||
repeated int32 repeated_int32 = 31;
|
||||
repeated int64 repeated_int64 = 32;
|
||||
repeated uint32 repeated_uint32 = 33;
|
||||
repeated uint64 repeated_uint64 = 34;
|
||||
repeated sint32 repeated_sint32 = 35;
|
||||
repeated sint64 repeated_sint64 = 36;
|
||||
repeated fixed32 repeated_fixed32 = 37;
|
||||
repeated fixed64 repeated_fixed64 = 38;
|
||||
repeated sfixed32 repeated_sfixed32 = 39;
|
||||
repeated sfixed64 repeated_sfixed64 = 40;
|
||||
repeated float repeated_float = 41;
|
||||
repeated double repeated_double = 42;
|
||||
repeated bool repeated_bool = 43;
|
||||
repeated string repeated_string = 44;
|
||||
repeated bytes repeated_bytes = 45;
|
||||
|
||||
repeated ForeignMessage repeated_foreign_message = 49;
|
||||
repeated Proto3Enum repeated_foreign_enum = 52;
|
||||
|
||||
|
||||
oneof oneof_field {
|
||||
uint32 oneof_uint32 = 111;
|
||||
ForeignMessage oneof_foreign_message = 112;
|
||||
string oneof_string = 113;
|
||||
bytes oneof_bytes = 114;
|
||||
}
|
||||
}
|
||||
|
||||
enum Proto3Enum {
|
||||
PROTO3_FOO = 0;
|
||||
PROTO3_BAR = 1;
|
||||
PROTO3_BAZ = 2;
|
||||
}
|
262
js/compatibility_tests/v3.1.0/test.proto
Normal file
262
js/compatibility_tests/v3.1.0/test.proto
Normal file
@ -0,0 +1,262 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Author: mwr@google.com (Mark Rawling)
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
option java_package = "com.google.apps.jspb.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
import "google/protobuf/descriptor.proto";
|
||||
|
||||
package jspb.test;
|
||||
|
||||
message Empty {
|
||||
}
|
||||
|
||||
enum OuterEnum {
|
||||
FOO = 1;
|
||||
BAR = 2;
|
||||
}
|
||||
|
||||
message EnumContainer {
|
||||
optional OuterEnum outer_enum = 1;
|
||||
}
|
||||
|
||||
message Simple1 {
|
||||
required string a_string = 1;
|
||||
repeated string a_repeated_string = 2;
|
||||
optional bool a_boolean = 3;
|
||||
}
|
||||
|
||||
// A message that differs from Simple1 only by name
|
||||
message Simple2 {
|
||||
required string a_string = 1;
|
||||
repeated string a_repeated_string = 2;
|
||||
}
|
||||
|
||||
message SpecialCases {
|
||||
required string normal = 1;
|
||||
// Examples of Js reserved names that are converted to pb_<name>.
|
||||
required string default = 2;
|
||||
required string function = 3;
|
||||
required string var = 4;
|
||||
}
|
||||
|
||||
message OptionalFields {
|
||||
message Nested {
|
||||
optional int32 an_int = 1;
|
||||
}
|
||||
optional string a_string = 1;
|
||||
required bool a_bool = 2;
|
||||
optional Nested a_nested_message = 3;
|
||||
repeated Nested a_repeated_message = 4;
|
||||
repeated string a_repeated_string = 5;
|
||||
}
|
||||
|
||||
message HasExtensions {
|
||||
optional string str1 = 1;
|
||||
optional string str2 = 2;
|
||||
optional string str3 = 3;
|
||||
extensions 10 to max;
|
||||
}
|
||||
|
||||
message Complex {
|
||||
message Nested {
|
||||
required int32 an_int = 2;
|
||||
}
|
||||
required string a_string = 1;
|
||||
required bool an_out_of_order_bool = 9;
|
||||
optional Nested a_nested_message = 4;
|
||||
repeated Nested a_repeated_message = 5;
|
||||
repeated string a_repeated_string = 7;
|
||||
}
|
||||
|
||||
message OuterMessage {
|
||||
// Make sure this doesn't conflict with the other Complex message.
|
||||
message Complex {
|
||||
optional int32 inner_complex_field = 1;
|
||||
}
|
||||
}
|
||||
|
||||
message IsExtension {
|
||||
extend HasExtensions {
|
||||
optional IsExtension ext_field = 100;
|
||||
}
|
||||
optional string ext1 = 1;
|
||||
|
||||
// Extensions of proto2 Descriptor messages will be ignored.
|
||||
extend google.protobuf.EnumOptions {
|
||||
optional string simple_option = 42113038;
|
||||
}
|
||||
}
|
||||
|
||||
message IndirectExtension {
|
||||
extend HasExtensions {
|
||||
optional Simple1 simple = 101;
|
||||
optional string str = 102;
|
||||
repeated string repeated_str = 103;
|
||||
repeated Simple1 repeated_simple = 104;
|
||||
}
|
||||
}
|
||||
|
||||
extend HasExtensions {
|
||||
optional Simple1 simple1 = 105;
|
||||
}
|
||||
|
||||
message DefaultValues {
|
||||
enum Enum {
|
||||
E1 = 13;
|
||||
E2 = 77;
|
||||
}
|
||||
optional string string_field = 1 [default="default<>\'\"abc"];
|
||||
optional bool bool_field = 2 [default=true];
|
||||
optional int64 int_field = 3 [default=11];
|
||||
optional Enum enum_field = 4 [default=E1];
|
||||
optional string empty_field = 6 [default=""];
|
||||
optional bytes bytes_field = 8 [default="moo"]; // Base64 encoding is "bW9v"
|
||||
}
|
||||
|
||||
message FloatingPointFields {
|
||||
optional float optional_float_field = 1;
|
||||
required float required_float_field = 2;
|
||||
repeated float repeated_float_field = 3;
|
||||
optional float default_float_field = 4 [default = 2.0];
|
||||
optional double optional_double_field = 5;
|
||||
required double required_double_field = 6;
|
||||
repeated double repeated_double_field = 7;
|
||||
optional double default_double_field = 8 [default = 2.0];
|
||||
}
|
||||
|
||||
message TestClone {
|
||||
optional string str = 1;
|
||||
optional Simple1 simple1 = 3;
|
||||
repeated Simple1 simple2 = 5;
|
||||
optional bytes bytes_field = 6;
|
||||
optional string unused = 7;
|
||||
extensions 10 to max;
|
||||
}
|
||||
|
||||
message CloneExtension {
|
||||
extend TestClone {
|
||||
optional CloneExtension ext_field = 100;
|
||||
}
|
||||
optional string ext = 2;
|
||||
}
|
||||
|
||||
message TestGroup {
|
||||
repeated group RepeatedGroup = 1 {
|
||||
required string id = 1;
|
||||
repeated bool some_bool = 2;
|
||||
}
|
||||
required group RequiredGroup = 2 {
|
||||
required string id = 1;
|
||||
}
|
||||
optional group OptionalGroup = 3 {
|
||||
required string id = 1;
|
||||
}
|
||||
optional string id = 4;
|
||||
required Simple2 required_simple = 5;
|
||||
optional Simple2 optional_simple = 6;
|
||||
}
|
||||
|
||||
message TestGroup1 {
|
||||
optional TestGroup.RepeatedGroup group = 1;
|
||||
}
|
||||
|
||||
message TestReservedNames {
|
||||
optional int32 extension = 1;
|
||||
extensions 10 to max;
|
||||
}
|
||||
|
||||
message TestReservedNamesExtension {
|
||||
extend TestReservedNames {
|
||||
optional int32 foo = 10;
|
||||
}
|
||||
}
|
||||
|
||||
message TestMessageWithOneof {
|
||||
|
||||
oneof partial_oneof {
|
||||
string pone = 3;
|
||||
string pthree = 5;
|
||||
}
|
||||
|
||||
oneof recursive_oneof {
|
||||
TestMessageWithOneof rone = 6;
|
||||
string rtwo = 7;
|
||||
}
|
||||
|
||||
optional bool normal_field = 8;
|
||||
repeated string repeated_field = 9;
|
||||
|
||||
oneof default_oneof_a {
|
||||
int32 aone = 10 [default = 1234];
|
||||
int32 atwo = 11;
|
||||
}
|
||||
|
||||
oneof default_oneof_b {
|
||||
int32 bone = 12;
|
||||
int32 btwo = 13 [default = 1234];
|
||||
}
|
||||
}
|
||||
|
||||
message TestEndsWithBytes {
|
||||
optional int32 value = 1;
|
||||
optional bytes data = 2;
|
||||
}
|
||||
|
||||
message TestMapFieldsNoBinary {
|
||||
map<string, string> map_string_string = 1;
|
||||
map<string, int32> map_string_int32 = 2;
|
||||
map<string, int64> map_string_int64 = 3;
|
||||
map<string, bool> map_string_bool = 4;
|
||||
map<string, double> map_string_double = 5;
|
||||
map<string, MapValueEnumNoBinary> map_string_enum = 6;
|
||||
map<string, MapValueMessageNoBinary> map_string_msg = 7;
|
||||
|
||||
map<int32, string> map_int32_string = 8;
|
||||
map<int64, string> map_int64_string = 9;
|
||||
map<bool, string> map_bool_string = 10;
|
||||
|
||||
optional TestMapFieldsNoBinary test_map_fields = 11;
|
||||
map<string, TestMapFieldsNoBinary> map_string_testmapfields = 12;
|
||||
}
|
||||
|
||||
enum MapValueEnumNoBinary {
|
||||
MAP_VALUE_FOO_NOBINARY = 0;
|
||||
MAP_VALUE_BAR_NOBINARY = 1;
|
||||
MAP_VALUE_BAZ_NOBINARY = 2;
|
||||
}
|
||||
|
||||
message MapValueMessageNoBinary {
|
||||
optional int32 foo = 1;
|
||||
}
|
54
js/compatibility_tests/v3.1.0/test2.proto
Normal file
54
js/compatibility_tests/v3.1.0/test2.proto
Normal file
@ -0,0 +1,54 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
option java_package = "com.google.apps.jspb.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
package jspb.test;
|
||||
|
||||
message TestExtensionsMessage {
|
||||
optional int32 intfield = 1;
|
||||
extensions 100 to max;
|
||||
}
|
||||
|
||||
message ExtensionMessage {
|
||||
extend TestExtensionsMessage {
|
||||
optional ExtensionMessage ext_field = 100;
|
||||
}
|
||||
optional string ext1 = 1;
|
||||
}
|
||||
|
||||
// Floating extensions are only supported when generating a _lib.js library.
|
||||
extend TestExtensionsMessage {
|
||||
optional ExtensionMessage floating_msg_field = 101;
|
||||
optional string floating_str_field = 102;
|
||||
}
|
53
js/compatibility_tests/v3.1.0/test3.proto
Normal file
53
js/compatibility_tests/v3.1.0/test3.proto
Normal 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.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
option java_package = "com.google.apps.jspb.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
package jspb.exttest;
|
||||
|
||||
message TestExtensionsMessage {
|
||||
optional int32 intfield = 1;
|
||||
extensions 100 to max;
|
||||
}
|
||||
|
||||
message ExtensionMessage {
|
||||
extend TestExtensionsMessage {
|
||||
optional ExtensionMessage ext_field = 100;
|
||||
}
|
||||
optional string ext1 = 1;
|
||||
}
|
||||
|
||||
extend TestExtensionsMessage {
|
||||
optional ExtensionMessage floating_msg_field = 101;
|
||||
optional string floating_str_field = 102;
|
||||
}
|
42
js/compatibility_tests/v3.1.0/test4.proto
Normal file
42
js/compatibility_tests/v3.1.0/test4.proto
Normal file
@ -0,0 +1,42 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
option java_package = "com.google.apps.jspb.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
package jspb.exttest;
|
||||
|
||||
import "test3.proto";
|
||||
|
||||
extend TestExtensionsMessage {
|
||||
optional ExtensionMessage floating_msg_field_two = 103;
|
||||
}
|
44
js/compatibility_tests/v3.1.0/test5.proto
Normal file
44
js/compatibility_tests/v3.1.0/test5.proto
Normal file
@ -0,0 +1,44 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
option java_package = "com.google.apps.jspb.proto";
|
||||
option java_multiple_files = true;
|
||||
|
||||
package jspb.exttest.beta;
|
||||
|
||||
message TestBetaExtensionsMessage {
|
||||
extensions 100 to max;
|
||||
}
|
||||
|
||||
extend TestBetaExtensionsMessage {
|
||||
optional string floating_str_field = 101;
|
||||
}
|
212
js/compatibility_tests/v3.1.0/testbinary.proto
Normal file
212
js/compatibility_tests/v3.1.0/testbinary.proto
Normal file
@ -0,0 +1,212 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// LINT: ALLOW_GROUPS
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
|
||||
package jspb.test;
|
||||
|
||||
// These types are borrowed from `unittest.proto` in the protobuf tree. We want
|
||||
// to ensure that the binary-format support will handle all field types
|
||||
// properly.
|
||||
message TestAllTypes {
|
||||
optional int32 optional_int32 = 1;
|
||||
optional int64 optional_int64 = 2;
|
||||
optional uint32 optional_uint32 = 3;
|
||||
optional uint64 optional_uint64 = 4;
|
||||
optional sint32 optional_sint32 = 5;
|
||||
optional sint64 optional_sint64 = 6;
|
||||
optional fixed32 optional_fixed32 = 7;
|
||||
optional fixed64 optional_fixed64 = 8;
|
||||
optional sfixed32 optional_sfixed32 = 9;
|
||||
optional sfixed64 optional_sfixed64 = 10;
|
||||
optional float optional_float = 11;
|
||||
optional double optional_double = 12;
|
||||
optional bool optional_bool = 13;
|
||||
optional string optional_string = 14;
|
||||
optional bytes optional_bytes = 15;
|
||||
optional group OptionalGroup = 16 {
|
||||
optional int32 a = 17;
|
||||
}
|
||||
|
||||
optional ForeignMessage optional_foreign_message = 19;
|
||||
optional ForeignEnum optional_foreign_enum = 22;
|
||||
|
||||
// Repeated
|
||||
repeated int32 repeated_int32 = 31;
|
||||
repeated int64 repeated_int64 = 32;
|
||||
repeated uint32 repeated_uint32 = 33;
|
||||
repeated uint64 repeated_uint64 = 34;
|
||||
repeated sint32 repeated_sint32 = 35;
|
||||
repeated sint64 repeated_sint64 = 36;
|
||||
repeated fixed32 repeated_fixed32 = 37;
|
||||
repeated fixed64 repeated_fixed64 = 38;
|
||||
repeated sfixed32 repeated_sfixed32 = 39;
|
||||
repeated sfixed64 repeated_sfixed64 = 40;
|
||||
repeated float repeated_float = 41;
|
||||
repeated double repeated_double = 42;
|
||||
repeated bool repeated_bool = 43;
|
||||
repeated string repeated_string = 44;
|
||||
repeated bytes repeated_bytes = 45;
|
||||
|
||||
repeated group RepeatedGroup = 46 {
|
||||
optional int32 a = 47;
|
||||
}
|
||||
|
||||
repeated ForeignMessage repeated_foreign_message = 49;
|
||||
repeated ForeignEnum repeated_foreign_enum = 52;
|
||||
|
||||
// Packed repeated
|
||||
repeated int32 packed_repeated_int32 = 61 [packed=true];
|
||||
repeated int64 packed_repeated_int64 = 62 [packed=true];
|
||||
repeated uint32 packed_repeated_uint32 = 63 [packed=true];
|
||||
repeated uint64 packed_repeated_uint64 = 64 [packed=true];
|
||||
repeated sint32 packed_repeated_sint32 = 65 [packed=true];
|
||||
repeated sint64 packed_repeated_sint64 = 66 [packed=true];
|
||||
repeated fixed32 packed_repeated_fixed32 = 67 [packed=true];
|
||||
repeated fixed64 packed_repeated_fixed64 = 68 [packed=true];
|
||||
repeated sfixed32 packed_repeated_sfixed32 = 69 [packed=true];
|
||||
repeated sfixed64 packed_repeated_sfixed64 = 70 [packed=true];
|
||||
repeated float packed_repeated_float = 71 [packed=true];
|
||||
repeated double packed_repeated_double = 72 [packed=true];
|
||||
repeated bool packed_repeated_bool = 73 [packed=true];
|
||||
|
||||
oneof oneof_field {
|
||||
uint32 oneof_uint32 = 111;
|
||||
ForeignMessage oneof_foreign_message = 112;
|
||||
string oneof_string = 113;
|
||||
bytes oneof_bytes = 114;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
message ForeignMessage {
|
||||
optional int32 c = 1;
|
||||
}
|
||||
|
||||
enum ForeignEnum {
|
||||
FOREIGN_FOO = 4;
|
||||
FOREIGN_BAR = 5;
|
||||
FOREIGN_BAZ = 6;
|
||||
}
|
||||
|
||||
message TestExtendable {
|
||||
extensions 1 to max;
|
||||
}
|
||||
|
||||
message ExtendsWithMessage {
|
||||
extend TestExtendable {
|
||||
optional ExtendsWithMessage optional_extension = 19;
|
||||
repeated ExtendsWithMessage repeated_extension = 49;
|
||||
}
|
||||
optional int32 foo = 1;
|
||||
}
|
||||
|
||||
extend TestExtendable {
|
||||
optional int32 extend_optional_int32 = 1;
|
||||
optional int64 extend_optional_int64 = 2;
|
||||
optional uint32 extend_optional_uint32 = 3;
|
||||
optional uint64 extend_optional_uint64 = 4;
|
||||
optional sint32 extend_optional_sint32 = 5;
|
||||
optional sint64 extend_optional_sint64 = 6;
|
||||
optional fixed32 extend_optional_fixed32 = 7;
|
||||
optional fixed64 extend_optional_fixed64 = 8;
|
||||
optional sfixed32 extend_optional_sfixed32 = 9;
|
||||
optional sfixed64 extend_optional_sfixed64 = 10;
|
||||
optional float extend_optional_float = 11;
|
||||
optional double extend_optional_double = 12;
|
||||
optional bool extend_optional_bool = 13;
|
||||
optional string extend_optional_string = 14;
|
||||
optional bytes extend_optional_bytes = 15;
|
||||
optional ForeignEnum extend_optional_foreign_enum = 22;
|
||||
|
||||
repeated int32 extend_repeated_int32 = 31;
|
||||
repeated int64 extend_repeated_int64 = 32;
|
||||
repeated uint32 extend_repeated_uint32 = 33;
|
||||
repeated uint64 extend_repeated_uint64 = 34;
|
||||
repeated sint32 extend_repeated_sint32 = 35;
|
||||
repeated sint64 extend_repeated_sint64 = 36;
|
||||
repeated fixed32 extend_repeated_fixed32 = 37;
|
||||
repeated fixed64 extend_repeated_fixed64 = 38;
|
||||
repeated sfixed32 extend_repeated_sfixed32 = 39;
|
||||
repeated sfixed64 extend_repeated_sfixed64 = 40;
|
||||
repeated float extend_repeated_float = 41;
|
||||
repeated double extend_repeated_double = 42;
|
||||
repeated bool extend_repeated_bool = 43;
|
||||
repeated string extend_repeated_string = 44;
|
||||
repeated bytes extend_repeated_bytes = 45;
|
||||
repeated ForeignEnum extend_repeated_foreign_enum = 52;
|
||||
|
||||
repeated int32 extend_packed_repeated_int32 = 61 [packed=true];
|
||||
repeated int64 extend_packed_repeated_int64 = 62 [packed=true];
|
||||
repeated uint32 extend_packed_repeated_uint32 = 63 [packed=true];
|
||||
repeated uint64 extend_packed_repeated_uint64 = 64 [packed=true];
|
||||
repeated sint32 extend_packed_repeated_sint32 = 65 [packed=true];
|
||||
repeated sint64 extend_packed_repeated_sint64 = 66 [packed=true];
|
||||
repeated fixed32 extend_packed_repeated_fixed32 = 67 [packed=true];
|
||||
repeated fixed64 extend_packed_repeated_fixed64 = 68 [packed=true];
|
||||
repeated sfixed32 extend_packed_repeated_sfixed32 = 69 [packed=true];
|
||||
repeated sfixed64 extend_packed_repeated_sfixed64 = 70 [packed=true];
|
||||
repeated float extend_packed_repeated_float = 71 [packed=true];
|
||||
repeated double extend_packed_repeated_double = 72 [packed=true];
|
||||
repeated bool extend_packed_repeated_bool = 73 [packed=true];
|
||||
repeated ForeignEnum extend_packed_repeated_foreign_enum = 82
|
||||
[packed=true];
|
||||
|
||||
}
|
||||
|
||||
message TestMapFields {
|
||||
map<string, string> map_string_string = 1;
|
||||
map<string, int32> map_string_int32 = 2;
|
||||
map<string, int64> map_string_int64 = 3;
|
||||
map<string, bool> map_string_bool = 4;
|
||||
map<string, double> map_string_double = 5;
|
||||
map<string, MapValueEnum> map_string_enum = 6;
|
||||
map<string, MapValueMessage> map_string_msg = 7;
|
||||
|
||||
map<int32, string> map_int32_string = 8;
|
||||
map<int64, string> map_int64_string = 9;
|
||||
map<bool, string> map_bool_string = 10;
|
||||
|
||||
optional TestMapFields test_map_fields = 11;
|
||||
map<string, TestMapFields> map_string_testmapfields = 12;
|
||||
}
|
||||
|
||||
enum MapValueEnum {
|
||||
MAP_VALUE_FOO = 0;
|
||||
MAP_VALUE_BAR = 1;
|
||||
MAP_VALUE_BAZ = 2;
|
||||
}
|
||||
|
||||
message MapValueMessage {
|
||||
optional int32 foo = 1;
|
||||
}
|
34
js/compatibility_tests/v3.1.0/testempty.proto
Normal file
34
js/compatibility_tests/v3.1.0/testempty.proto
Normal file
@ -0,0 +1,34 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package javatests.com.google.apps.jspb;
|
||||
|
@ -41,7 +41,6 @@ goog.provide('jspb.Message');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.require('goog.json');
|
||||
goog.require('jspb.Map');
|
||||
|
||||
// Not needed in compilation units that have no protos with xids.
|
||||
@ -192,8 +191,8 @@ goog.define('jspb.Message.GENERATE_FROM_OBJECT', !goog.DISALLOW_TEST_ONLY_CODE);
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to generate toString methods for objects. Turn
|
||||
* this off if you do use toString in your project and want to trim it from
|
||||
* compiled JS.
|
||||
* this off if you do not use toString in your project and want to trim it
|
||||
* from the compiled JS.
|
||||
*/
|
||||
goog.define('jspb.Message.GENERATE_TO_STRING', true);
|
||||
|
||||
@ -351,7 +350,7 @@ jspb.Message.initialize = function(
|
||||
// which would otherwise go unused.
|
||||
msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0;
|
||||
msg.array = data;
|
||||
jspb.Message.materializeExtensionObject_(msg, suggestedPivot);
|
||||
jspb.Message.initPivotAndExtensionObject_(msg, suggestedPivot);
|
||||
msg.convertedFloatingPointFields_ = {};
|
||||
|
||||
if (repeatedFields) {
|
||||
@ -364,6 +363,7 @@ jspb.Message.initialize = function(
|
||||
jspb.Message.EMPTY_LIST_SENTINEL_ :
|
||||
[]);
|
||||
} else {
|
||||
jspb.Message.maybeInitEmptyExtensionObject_(msg);
|
||||
msg.extensionObject_[fieldNumber] =
|
||||
msg.extensionObject_[fieldNumber] ||
|
||||
(jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS ?
|
||||
@ -408,17 +408,16 @@ jspb.Message.isArray_ = function(o) {
|
||||
|
||||
|
||||
/**
|
||||
* Ensures that the array contains an extension object if necessary.
|
||||
* If the array contains an extension object in its last position, then the
|
||||
* object is kept in place and its position is used as the pivot. If not, then
|
||||
* create an extension object using suggestedPivot. If suggestedPivot is -1,
|
||||
* we don't have an extension object at all, in which case all fields are stored
|
||||
* in the array.
|
||||
* object is kept in place and its position is used as the pivot. If not,
|
||||
* decides the pivot of the message based on suggestedPivot without
|
||||
* materializing the extension object.
|
||||
*
|
||||
* @param {!jspb.Message} msg The JsPb proto to modify.
|
||||
* @param {number} suggestedPivot See description for initialize().
|
||||
* @private
|
||||
*/
|
||||
jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) {
|
||||
jspb.Message.initPivotAndExtensionObject_ = function(msg, suggestedPivot) {
|
||||
if (msg.array.length) {
|
||||
var foundIndex = msg.array.length - 1;
|
||||
var obj = msg.array[foundIndex];
|
||||
@ -434,26 +433,17 @@ jspb.Message.materializeExtensionObject_ = function(msg, suggestedPivot) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// This complexity exists because we keep all extension fields in the
|
||||
// extensionObject_ regardless of proto field number. Changing this would
|
||||
// simplify the code here, but it would require changing the serialization
|
||||
// format from the server, which is not backwards compatible.
|
||||
// TODO(jshneier): Should we just treat extension fields the same as
|
||||
// non-extension fields, and select whether they appear in the object or in
|
||||
// the array purely based on tag number? This would allow simplifying all the
|
||||
// get/setExtension logic, but it would require the breaking change described
|
||||
// above.
|
||||
|
||||
if (suggestedPivot > -1) {
|
||||
msg.pivot_ = suggestedPivot;
|
||||
var pivotIndex = jspb.Message.getIndex_(msg, suggestedPivot);
|
||||
if (!jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) {
|
||||
msg.extensionObject_ = msg.array[pivotIndex] = {};
|
||||
} else {
|
||||
// Initialize to null to avoid changing the shape of the proto when it
|
||||
// gets eventually set.
|
||||
msg.extensionObject_ = null;
|
||||
}
|
||||
// Avoid changing the shape of the proto with an empty extension object by
|
||||
// deferring the materialization of the extension object until the first
|
||||
// time a field set into it (may be due to getting a repeated proto field
|
||||
// from it, in which case a new empty array is set into it at first).
|
||||
msg.extensionObject_ = null;
|
||||
} else {
|
||||
// suggestedPivot is -1, which means that we don't have an extension object
|
||||
// at all, in which case all fields are stored in the array.
|
||||
msg.pivot_ = Number.MAX_VALUE;
|
||||
}
|
||||
};
|
||||
@ -513,7 +503,7 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions,
|
||||
for (var fieldNumber in extensions) {
|
||||
var fieldInfo = extensions[fieldNumber];
|
||||
var value = getExtensionFn.call(proto, fieldInfo);
|
||||
if (goog.isDefAndNotNull(value)) {
|
||||
if (value != null) {
|
||||
for (var name in fieldInfo.fieldName) {
|
||||
if (fieldInfo.fieldName.hasOwnProperty(name)) {
|
||||
break; // the compiled field name
|
||||
@ -557,7 +547,7 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
|
||||
'without binary serialization support');
|
||||
}
|
||||
var value = getExtensionFn.call(proto, fieldInfo);
|
||||
if (goog.isDefAndNotNull(value)) {
|
||||
if (value != null) {
|
||||
if (fieldInfo.isMessageType()) {
|
||||
// If the message type of the extension was generated without binary
|
||||
// support, there may not be a binary message serializer function, and
|
||||
@ -647,6 +637,9 @@ jspb.Message.getField = function(msg, fieldNumber) {
|
||||
}
|
||||
return val;
|
||||
} else {
|
||||
if (!msg.extensionObject_) {
|
||||
return undefined;
|
||||
}
|
||||
var val = msg.extensionObject_[fieldNumber];
|
||||
if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
|
||||
return msg.extensionObject_[fieldNumber] = [];
|
||||
@ -656,6 +649,32 @@ jspb.Message.getField = function(msg, fieldNumber) {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of a non-extension repeated field.
|
||||
* @param {!jspb.Message} msg A jspb proto.
|
||||
* @param {number} fieldNumber The field number.
|
||||
* @return {!Array}
|
||||
* The field's value.
|
||||
* @protected
|
||||
*/
|
||||
jspb.Message.getRepeatedField = function(msg, fieldNumber) {
|
||||
if (fieldNumber < msg.pivot_) {
|
||||
var index = jspb.Message.getIndex_(msg, fieldNumber);
|
||||
var val = msg.array[index];
|
||||
if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
|
||||
return msg.array[index] = [];
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
var val = msg.extensionObject_[fieldNumber];
|
||||
if (val === jspb.Message.EMPTY_LIST_SENTINEL_) {
|
||||
return msg.extensionObject_[fieldNumber] = [];
|
||||
}
|
||||
return val;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the value of an optional float or double field.
|
||||
* @param {!jspb.Message} msg A jspb proto.
|
||||
@ -678,7 +697,7 @@ jspb.Message.getOptionalFloatingPointField = function(msg, fieldNumber) {
|
||||
* @protected
|
||||
*/
|
||||
jspb.Message.getRepeatedFloatingPointField = function(msg, fieldNumber) {
|
||||
var values = jspb.Message.getField(msg, fieldNumber);
|
||||
var values = jspb.Message.getRepeatedField(msg, fieldNumber);
|
||||
if (!msg.convertedFloatingPointFields_) {
|
||||
msg.convertedFloatingPointFields_ = {};
|
||||
}
|
||||
@ -864,6 +883,7 @@ jspb.Message.setField = function(msg, fieldNumber, value) {
|
||||
if (fieldNumber < msg.pivot_) {
|
||||
msg.array[jspb.Message.getIndex_(msg, fieldNumber)] = value;
|
||||
} else {
|
||||
jspb.Message.maybeInitEmptyExtensionObject_(msg);
|
||||
msg.extensionObject_[fieldNumber] = value;
|
||||
}
|
||||
};
|
||||
@ -878,7 +898,7 @@ jspb.Message.setField = function(msg, fieldNumber, value) {
|
||||
* @protected
|
||||
*/
|
||||
jspb.Message.addToRepeatedField = function(msg, fieldNumber, value, opt_index) {
|
||||
var arr = jspb.Message.getField(msg, fieldNumber);
|
||||
var arr = jspb.Message.getRepeatedField(msg, fieldNumber);
|
||||
if (opt_index != undefined) {
|
||||
arr.splice(opt_index, 0, value);
|
||||
} else {
|
||||
@ -1006,7 +1026,7 @@ jspb.Message.wrapRepeatedField_ = function(msg, ctor, fieldNumber) {
|
||||
msg.wrappers_ = {};
|
||||
}
|
||||
if (!msg.wrappers_[fieldNumber]) {
|
||||
var data = jspb.Message.getField(msg, fieldNumber);
|
||||
var data = jspb.Message.getRepeatedField(msg, fieldNumber);
|
||||
for (var wrappers = [], i = 0; i < data.length; i++) {
|
||||
wrappers[i] = new ctor(data[i]);
|
||||
}
|
||||
@ -1101,7 +1121,7 @@ jspb.Message.addToRepeatedWrapperField = function(
|
||||
wrapperArray = msg.wrappers_[fieldNumber] = [];
|
||||
}
|
||||
var insertedValue = value ? value : new ctor();
|
||||
var array = jspb.Message.getField(msg, fieldNumber);
|
||||
var array = jspb.Message.getRepeatedField(msg, fieldNumber);
|
||||
if (index != undefined) {
|
||||
wrapperArray.splice(index, 0, insertedValue);
|
||||
array.splice(index, 0, insertedValue.toArray());
|
||||
|
@ -33,6 +33,7 @@
|
||||
goog.setTestOnly();
|
||||
|
||||
goog.require('goog.json');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
@ -64,11 +65,13 @@ goog.require('proto.jspb.test.floatingStrField');
|
||||
goog.require('proto.jspb.test.HasExtensions');
|
||||
goog.require('proto.jspb.test.IndirectExtension');
|
||||
goog.require('proto.jspb.test.IsExtension');
|
||||
goog.require('proto.jspb.test.MessageWithLargeFieldTags');
|
||||
goog.require('proto.jspb.test.OptionalFields');
|
||||
goog.require('proto.jspb.test.OuterEnum');
|
||||
goog.require('proto.jspb.test.OuterMessage.Complex');
|
||||
goog.require('proto.jspb.test.Simple1');
|
||||
goog.require('proto.jspb.test.Simple2');
|
||||
goog.require('proto.jspb.test.SingularsWithLargeFieldTags');
|
||||
goog.require('proto.jspb.test.SpecialCases');
|
||||
goog.require('proto.jspb.test.TestClone');
|
||||
goog.require('proto.jspb.test.TestEndsWithBytes');
|
||||
@ -83,8 +86,6 @@ goog.require('proto.jspb.test.ExtensionMessage');
|
||||
goog.require('proto.jspb.test.TestExtensionsMessage');
|
||||
|
||||
|
||||
|
||||
|
||||
describe('Message test suite', function() {
|
||||
it('testEmptyProto', function() {
|
||||
var empty1 = new proto.jspb.test.Empty([]);
|
||||
@ -273,12 +274,6 @@ describe('Message test suite', function() {
|
||||
assertFalse(response.hasEnumField());
|
||||
});
|
||||
|
||||
it('testMessageRegistration', /** @suppress {visibility} */ function() {
|
||||
// goog.require(SomeResponse) will include its library, which will in
|
||||
// turn add SomeResponse to the message registry.
|
||||
assertEquals(jspb.Message.registry_['res'], proto.jspb.test.SomeResponse);
|
||||
});
|
||||
|
||||
it('testClearFields', function() {
|
||||
var data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
|
||||
var foo = new proto.jspb.test.OptionalFields(data);
|
||||
@ -661,12 +656,7 @@ describe('Message test suite', function() {
|
||||
|
||||
it('testInitialization_emptyArray', function() {
|
||||
var msg = new proto.jspb.test.HasExtensions([]);
|
||||
if (jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS) {
|
||||
assertArrayEquals([], msg.toArray());
|
||||
} else {
|
||||
// Extension object is created past all regular fields.
|
||||
assertArrayEquals([,,, {}], msg.toArray());
|
||||
}
|
||||
assertArrayEquals([], msg.toArray());
|
||||
});
|
||||
|
||||
it('testInitialization_justExtensionObject', function() {
|
||||
|
@ -86,4 +86,5 @@ enum Proto3Enum {
|
||||
PROTO3_FOO = 0;
|
||||
PROTO3_BAR = 1;
|
||||
PROTO3_BAZ = 2;
|
||||
MSG_PROTO3_BAH = 3;
|
||||
}
|
||||
|
@ -235,6 +235,13 @@ message TestEndsWithBytes {
|
||||
}
|
||||
|
||||
|
||||
message Int64Types {
|
||||
optional int64 int64_normal = 1 [jstype=JS_NORMAL];
|
||||
optional sint64 int64_string = 2 [jstype=JS_STRING];
|
||||
optional uint64 int64_number = 3 [jstype=JS_NUMBER];
|
||||
|
||||
}
|
||||
|
||||
message TestMapFieldsNoBinary {
|
||||
|
||||
map<string, string> map_string_string = 1;
|
||||
@ -271,3 +278,4 @@ message Deeply {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,9 +370,8 @@ class TextFormatTest(unittest.TestCase):
|
||||
def testMergeBadExtension(self):
|
||||
message = unittest_pb2.TestAllExtensions()
|
||||
text = '[unknown_extension]: 8\n'
|
||||
self.assertRaisesWithMessage(
|
||||
self.assertRaises(
|
||||
text_format.ParseError,
|
||||
'1:2 : Extension "unknown_extension" not registered.',
|
||||
text_format.Merge, text, message)
|
||||
message = unittest_pb2.TestAllTypes()
|
||||
self.assertRaisesWithMessage(
|
||||
|
@ -406,6 +406,8 @@ class FieldDescriptor(DescriptorBase):
|
||||
|
||||
containing_oneof: (OneofDescriptor) If the field is a member of a oneof
|
||||
union, contains its descriptor. Otherwise, None.
|
||||
|
||||
file: (FileDescriptor) Reference to file descriptor.
|
||||
"""
|
||||
|
||||
# Must be consistent with C++ FieldDescriptor::Type enum in
|
||||
@ -490,7 +492,8 @@ class FieldDescriptor(DescriptorBase):
|
||||
def __new__(cls, name, full_name, index, number, type, cpp_type, label,
|
||||
default_value, message_type, enum_type, containing_type,
|
||||
is_extension, extension_scope, options=None,
|
||||
has_default_value=True, containing_oneof=None, json_name=None):
|
||||
has_default_value=True, containing_oneof=None, json_name=None,
|
||||
file=None):
|
||||
_message.Message._CheckCalledFromGeneratedFile()
|
||||
if is_extension:
|
||||
return _message.default_pool.FindExtensionByName(full_name)
|
||||
@ -500,7 +503,8 @@ class FieldDescriptor(DescriptorBase):
|
||||
def __init__(self, name, full_name, index, number, type, cpp_type, label,
|
||||
default_value, message_type, enum_type, containing_type,
|
||||
is_extension, extension_scope, options=None,
|
||||
has_default_value=True, containing_oneof=None, json_name=None):
|
||||
has_default_value=True, containing_oneof=None, json_name=None,
|
||||
file=None):
|
||||
"""The arguments are as described in the description of FieldDescriptor
|
||||
attributes above.
|
||||
|
||||
@ -511,6 +515,7 @@ class FieldDescriptor(DescriptorBase):
|
||||
super(FieldDescriptor, self).__init__(options, 'FieldOptions')
|
||||
self.name = name
|
||||
self.full_name = full_name
|
||||
self.file = file
|
||||
self._camelcase_name = None
|
||||
if json_name is None:
|
||||
self.json_name = _ToJsonName(name)
|
||||
|
@ -134,8 +134,7 @@ def _ExtractSymbols(desc_proto, package):
|
||||
Yields:
|
||||
The fully qualified name found in the descriptor.
|
||||
"""
|
||||
|
||||
message_name = '.'.join((package, desc_proto.name))
|
||||
message_name = package + '.' + desc_proto.name if package else desc_proto.name
|
||||
yield message_name
|
||||
for nested_type in desc_proto.nested_type:
|
||||
for symbol in _ExtractSymbols(nested_type, message_name):
|
||||
|
@ -257,7 +257,7 @@ class DescriptorPool(object):
|
||||
self._AddFileDescriptor(file_desc)
|
||||
# TODO(jieluo): This is a temporary solution for FieldDescriptor.file.
|
||||
# Remove it when FieldDescriptor.file is added in code gen.
|
||||
for extension in file_desc.extensions_by_name.values():
|
||||
for extension in file_desc.extensions_by_name.itervalues():
|
||||
self._file_desc_by_toplevel_extension[
|
||||
extension.full_name] = file_desc
|
||||
|
||||
@ -328,6 +328,11 @@ class DescriptorPool(object):
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
return self._service_descriptors[symbol].file
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
return self._FindFileContainingSymbolInDb(symbol)
|
||||
except KeyError:
|
||||
@ -344,7 +349,6 @@ class DescriptorPool(object):
|
||||
message = self.FindMessageTypeByName(message_name)
|
||||
assert message.extensions_by_name[extension_name]
|
||||
return message.file
|
||||
|
||||
except KeyError:
|
||||
raise KeyError('Cannot find a file containing %s' % symbol)
|
||||
|
||||
@ -557,7 +561,8 @@ class DescriptorPool(object):
|
||||
|
||||
for index, extension_proto in enumerate(file_proto.extension):
|
||||
extension_desc = self._MakeFieldDescriptor(
|
||||
extension_proto, file_proto.package, index, is_extension=True)
|
||||
extension_proto, file_proto.package, index, file_descriptor,
|
||||
is_extension=True)
|
||||
extension_desc.containing_type = self._GetTypeFromScope(
|
||||
file_descriptor.package, extension_proto.extendee, scope)
|
||||
self._SetFieldType(extension_proto, extension_desc,
|
||||
@ -623,10 +628,10 @@ class DescriptorPool(object):
|
||||
enums = [
|
||||
self._ConvertEnumDescriptor(enum, desc_name, file_desc, None, scope)
|
||||
for enum in desc_proto.enum_type]
|
||||
fields = [self._MakeFieldDescriptor(field, desc_name, index)
|
||||
fields = [self._MakeFieldDescriptor(field, desc_name, index, file_desc)
|
||||
for index, field in enumerate(desc_proto.field)]
|
||||
extensions = [
|
||||
self._MakeFieldDescriptor(extension, desc_name, index,
|
||||
self._MakeFieldDescriptor(extension, desc_name, index, file_desc,
|
||||
is_extension=True)
|
||||
for index, extension in enumerate(desc_proto.extension)]
|
||||
oneofs = [
|
||||
@ -708,7 +713,7 @@ class DescriptorPool(object):
|
||||
return desc
|
||||
|
||||
def _MakeFieldDescriptor(self, field_proto, message_name, index,
|
||||
is_extension=False):
|
||||
file_desc, is_extension=False):
|
||||
"""Creates a field descriptor from a FieldDescriptorProto.
|
||||
|
||||
For message and enum type fields, this method will do a look up
|
||||
@ -721,6 +726,7 @@ class DescriptorPool(object):
|
||||
field_proto: The proto describing the field.
|
||||
message_name: The name of the containing message.
|
||||
index: Index of the field
|
||||
file_desc: The file containing the field descriptor.
|
||||
is_extension: Indication that this field is for an extension.
|
||||
|
||||
Returns:
|
||||
@ -747,7 +753,8 @@ class DescriptorPool(object):
|
||||
default_value=None,
|
||||
is_extension=is_extension,
|
||||
extension_scope=None,
|
||||
options=_OptionsOrNone(field_proto))
|
||||
options=_OptionsOrNone(field_proto),
|
||||
file=file_desc)
|
||||
|
||||
def _SetAllFieldTypes(self, package, desc_proto, scope):
|
||||
"""Sets all the descriptor's fields's types.
|
||||
|
@ -100,6 +100,27 @@ if _implementation_version_str != '2':
|
||||
_implementation_version = int(_implementation_version_str)
|
||||
|
||||
|
||||
# Detect if serialization should be deterministic by default
|
||||
try:
|
||||
# The presence of this module in a build allows the proto implementation to
|
||||
# be upgraded merely via build deps.
|
||||
#
|
||||
# NOTE: Merely importing this automatically enables deterministic proto
|
||||
# serialization for C++ code, but we still need to export it as a boolean so
|
||||
# that we can do the same for `_implementation_type == 'python'`.
|
||||
#
|
||||
# NOTE2: It is possible for C++ code to enable deterministic serialization by
|
||||
# default _without_ affecting Python code, if the C++ implementation is not in
|
||||
# use by this module. That is intended behavior, so we don't actually expose
|
||||
# this boolean outside of this module.
|
||||
#
|
||||
# pylint: disable=g-import-not-at-top,unused-import
|
||||
from google.protobuf import enable_deterministic_proto_serialization
|
||||
_python_deterministic_proto_serialization = True
|
||||
except ImportError:
|
||||
_python_deterministic_proto_serialization = False
|
||||
|
||||
|
||||
# Usage of this function is discouraged. Clients shouldn't care which
|
||||
# implementation of the API is in use. Note that there is no guarantee
|
||||
# that differences between APIs will be maintained.
|
||||
@ -111,3 +132,8 @@ def Type():
|
||||
# See comment on 'Type' above.
|
||||
def Version():
|
||||
return _implementation_version
|
||||
|
||||
|
||||
# For internal use only
|
||||
def IsPythonDefaultSerializationDeterministic():
|
||||
return _python_deterministic_proto_serialization
|
||||
|
@ -131,11 +131,19 @@ class DescriptorPoolTest(unittest.TestCase):
|
||||
self.assertEqual('google/protobuf/internal/factory_test2.proto',
|
||||
file_desc4.name)
|
||||
|
||||
file_desc5 = self.pool.FindFileContainingSymbol(
|
||||
'protobuf_unittest.TestService')
|
||||
self.assertIsInstance(file_desc5, descriptor.FileDescriptor)
|
||||
self.assertEqual('google/protobuf/unittest.proto',
|
||||
file_desc5.name)
|
||||
|
||||
# Tests the generated pool.
|
||||
assert descriptor_pool.Default().FindFileContainingSymbol(
|
||||
'google.protobuf.python.internal.Factory2Message.one_more_field')
|
||||
assert descriptor_pool.Default().FindFileContainingSymbol(
|
||||
'google.protobuf.python.internal.another_field')
|
||||
assert descriptor_pool.Default().FindFileContainingSymbol(
|
||||
'protobuf_unittest.TestService')
|
||||
|
||||
def testFindFileContainingSymbolFailure(self):
|
||||
with self.assertRaises(KeyError):
|
||||
@ -506,10 +514,10 @@ class MessageType(object):
|
||||
subtype.CheckType(test, desc, name, file_desc)
|
||||
|
||||
for index, (name, field) in enumerate(self.field_list):
|
||||
field.CheckField(test, desc, name, index)
|
||||
field.CheckField(test, desc, name, index, file_desc)
|
||||
|
||||
for index, (name, field) in enumerate(self.extensions):
|
||||
field.CheckField(test, desc, name, index)
|
||||
field.CheckField(test, desc, name, index, file_desc)
|
||||
|
||||
|
||||
class EnumField(object):
|
||||
@ -519,7 +527,7 @@ class EnumField(object):
|
||||
self.type_name = type_name
|
||||
self.default_value = default_value
|
||||
|
||||
def CheckField(self, test, msg_desc, name, index):
|
||||
def CheckField(self, test, msg_desc, name, index, file_desc):
|
||||
field_desc = msg_desc.fields_by_name[name]
|
||||
enum_desc = msg_desc.enum_types_by_name[self.type_name]
|
||||
test.assertEqual(name, field_desc.name)
|
||||
@ -536,6 +544,7 @@ class EnumField(object):
|
||||
test.assertFalse(enum_desc.values_by_name[self.default_value].has_options)
|
||||
test.assertEqual(msg_desc, field_desc.containing_type)
|
||||
test.assertEqual(enum_desc, field_desc.enum_type)
|
||||
test.assertEqual(file_desc, enum_desc.file)
|
||||
|
||||
|
||||
class MessageField(object):
|
||||
@ -544,7 +553,7 @@ class MessageField(object):
|
||||
self.number = number
|
||||
self.type_name = type_name
|
||||
|
||||
def CheckField(self, test, msg_desc, name, index):
|
||||
def CheckField(self, test, msg_desc, name, index, file_desc):
|
||||
field_desc = msg_desc.fields_by_name[name]
|
||||
field_type_desc = msg_desc.nested_types_by_name[self.type_name]
|
||||
test.assertEqual(name, field_desc.name)
|
||||
@ -558,6 +567,7 @@ class MessageField(object):
|
||||
test.assertFalse(field_desc.has_default_value)
|
||||
test.assertEqual(msg_desc, field_desc.containing_type)
|
||||
test.assertEqual(field_type_desc, field_desc.message_type)
|
||||
test.assertEqual(file_desc, field_desc.file)
|
||||
|
||||
|
||||
class StringField(object):
|
||||
@ -566,7 +576,7 @@ class StringField(object):
|
||||
self.number = number
|
||||
self.default_value = default_value
|
||||
|
||||
def CheckField(self, test, msg_desc, name, index):
|
||||
def CheckField(self, test, msg_desc, name, index, file_desc):
|
||||
field_desc = msg_desc.fields_by_name[name]
|
||||
test.assertEqual(name, field_desc.name)
|
||||
expected_field_full_name = '.'.join([msg_desc.full_name, name])
|
||||
@ -578,6 +588,7 @@ class StringField(object):
|
||||
field_desc.cpp_type)
|
||||
test.assertTrue(field_desc.has_default_value)
|
||||
test.assertEqual(self.default_value, field_desc.default_value)
|
||||
test.assertEqual(file_desc, field_desc.file)
|
||||
|
||||
|
||||
class ExtensionField(object):
|
||||
@ -586,7 +597,7 @@ class ExtensionField(object):
|
||||
self.number = number
|
||||
self.extended_type = extended_type
|
||||
|
||||
def CheckField(self, test, msg_desc, name, index):
|
||||
def CheckField(self, test, msg_desc, name, index, file_desc):
|
||||
field_desc = msg_desc.extensions_by_name[name]
|
||||
test.assertEqual(name, field_desc.name)
|
||||
expected_field_full_name = '.'.join([msg_desc.full_name, name])
|
||||
@ -601,6 +612,7 @@ class ExtensionField(object):
|
||||
test.assertEqual(msg_desc, field_desc.extension_scope)
|
||||
test.assertEqual(msg_desc, field_desc.message_type)
|
||||
test.assertEqual(self.extended_type, field_desc.containing_type.name)
|
||||
test.assertEqual(file_desc, field_desc.file)
|
||||
|
||||
|
||||
class AddDescriptorTest(unittest.TestCase):
|
||||
@ -746,15 +758,10 @@ class AddDescriptorTest(unittest.TestCase):
|
||||
self.assertIs(options, file_descriptor.GetOptions())
|
||||
|
||||
|
||||
@unittest.skipIf(
|
||||
api_implementation.Type() != 'cpp',
|
||||
'default_pool is only supported by the C++ implementation')
|
||||
class DefaultPoolTest(unittest.TestCase):
|
||||
|
||||
def testFindMethods(self):
|
||||
# pylint: disable=g-import-not-at-top
|
||||
from google.protobuf.pyext import _message
|
||||
pool = _message.default_pool
|
||||
pool = descriptor_pool.Default()
|
||||
self.assertIs(
|
||||
pool.FindFileByName('google/protobuf/unittest.proto'),
|
||||
unittest_pb2.DESCRIPTOR)
|
||||
@ -764,20 +771,23 @@ class DefaultPoolTest(unittest.TestCase):
|
||||
self.assertIs(
|
||||
pool.FindFieldByName('protobuf_unittest.TestAllTypes.optional_int32'),
|
||||
unittest_pb2.TestAllTypes.DESCRIPTOR.fields_by_name['optional_int32'])
|
||||
self.assertIs(
|
||||
pool.FindEnumTypeByName('protobuf_unittest.ForeignEnum'),
|
||||
unittest_pb2.ForeignEnum.DESCRIPTOR)
|
||||
if api_implementation.Type() != 'cpp':
|
||||
self.skipTest('Only the C++ implementation correctly indexes all types')
|
||||
self.assertIs(
|
||||
pool.FindExtensionByName('protobuf_unittest.optional_int32_extension'),
|
||||
unittest_pb2.DESCRIPTOR.extensions_by_name['optional_int32_extension'])
|
||||
self.assertIs(
|
||||
pool.FindEnumTypeByName('protobuf_unittest.ForeignEnum'),
|
||||
unittest_pb2.ForeignEnum.DESCRIPTOR)
|
||||
self.assertIs(
|
||||
pool.FindOneofByName('protobuf_unittest.TestAllTypes.oneof_field'),
|
||||
unittest_pb2.TestAllTypes.DESCRIPTOR.oneofs_by_name['oneof_field'])
|
||||
self.assertIs(
|
||||
pool.FindServiceByName('protobuf_unittest.TestService'),
|
||||
unittest_pb2.DESCRIPTOR.services_by_name['TestService'])
|
||||
|
||||
def testAddFileDescriptor(self):
|
||||
# pylint: disable=g-import-not-at-top
|
||||
from google.protobuf.pyext import _message
|
||||
pool = _message.default_pool
|
||||
pool = descriptor_pool.Default()
|
||||
file_desc = descriptor_pb2.FileDescriptorProto(name='some/file.proto')
|
||||
pool.Add(file_desc)
|
||||
pool.AddSerializedFile(file_desc.SerializeToString())
|
||||
|
@ -521,6 +521,12 @@ class GeneratedDescriptorTest(unittest.TestCase):
|
||||
del enum
|
||||
self.assertEqual('FOO', next(values_iter).name)
|
||||
|
||||
def testServiceDescriptor(self):
|
||||
service_descriptor = unittest_pb2.DESCRIPTOR.services_by_name['TestService']
|
||||
self.assertEqual(service_descriptor.name, 'TestService')
|
||||
self.assertEqual(service_descriptor.methods[0].name, 'Foo')
|
||||
self.assertIs(service_descriptor.file, unittest_pb2.DESCRIPTOR)
|
||||
|
||||
|
||||
class DescriptorCopyToProtoTest(unittest.TestCase):
|
||||
"""Tests for CopyTo functions of Descriptor."""
|
||||
|
@ -372,7 +372,7 @@ def MapSizer(field_descriptor, is_message_map):
|
||||
def _VarintEncoder():
|
||||
"""Return an encoder for a basic varint value (does not include tag)."""
|
||||
|
||||
def EncodeVarint(write, value):
|
||||
def EncodeVarint(write, value, unused_deterministic):
|
||||
bits = value & 0x7f
|
||||
value >>= 7
|
||||
while value:
|
||||
@ -388,7 +388,7 @@ def _SignedVarintEncoder():
|
||||
"""Return an encoder for a basic signed varint value (does not include
|
||||
tag)."""
|
||||
|
||||
def EncodeSignedVarint(write, value):
|
||||
def EncodeSignedVarint(write, value, unused_deterministic):
|
||||
if value < 0:
|
||||
value += (1 << 64)
|
||||
bits = value & 0x7f
|
||||
@ -411,7 +411,7 @@ def _VarintBytes(value):
|
||||
called at startup time so it doesn't need to be fast."""
|
||||
|
||||
pieces = []
|
||||
_EncodeVarint(pieces.append, value)
|
||||
_EncodeVarint(pieces.append, value, True)
|
||||
return b"".join(pieces)
|
||||
|
||||
|
||||
@ -440,27 +440,27 @@ def _SimpleEncoder(wire_type, encode_value, compute_value_size):
|
||||
if is_packed:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
|
||||
local_EncodeVarint = _EncodeVarint
|
||||
def EncodePackedField(write, value):
|
||||
def EncodePackedField(write, value, deterministic):
|
||||
write(tag_bytes)
|
||||
size = 0
|
||||
for element in value:
|
||||
size += compute_value_size(element)
|
||||
local_EncodeVarint(write, size)
|
||||
local_EncodeVarint(write, size, deterministic)
|
||||
for element in value:
|
||||
encode_value(write, element)
|
||||
encode_value(write, element, deterministic)
|
||||
return EncodePackedField
|
||||
elif is_repeated:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, deterministic):
|
||||
for element in value:
|
||||
write(tag_bytes)
|
||||
encode_value(write, element)
|
||||
encode_value(write, element, deterministic)
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, deterministic):
|
||||
write(tag_bytes)
|
||||
return encode_value(write, value)
|
||||
return encode_value(write, value, deterministic)
|
||||
return EncodeField
|
||||
|
||||
return SpecificEncoder
|
||||
@ -474,27 +474,27 @@ def _ModifiedEncoder(wire_type, encode_value, compute_value_size, modify_value):
|
||||
if is_packed:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
|
||||
local_EncodeVarint = _EncodeVarint
|
||||
def EncodePackedField(write, value):
|
||||
def EncodePackedField(write, value, deterministic):
|
||||
write(tag_bytes)
|
||||
size = 0
|
||||
for element in value:
|
||||
size += compute_value_size(modify_value(element))
|
||||
local_EncodeVarint(write, size)
|
||||
local_EncodeVarint(write, size, deterministic)
|
||||
for element in value:
|
||||
encode_value(write, modify_value(element))
|
||||
encode_value(write, modify_value(element), deterministic)
|
||||
return EncodePackedField
|
||||
elif is_repeated:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, deterministic):
|
||||
for element in value:
|
||||
write(tag_bytes)
|
||||
encode_value(write, modify_value(element))
|
||||
encode_value(write, modify_value(element), deterministic)
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, deterministic):
|
||||
write(tag_bytes)
|
||||
return encode_value(write, modify_value(value))
|
||||
return encode_value(write, modify_value(value), deterministic)
|
||||
return EncodeField
|
||||
|
||||
return SpecificEncoder
|
||||
@ -515,22 +515,22 @@ def _StructPackEncoder(wire_type, format):
|
||||
if is_packed:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
|
||||
local_EncodeVarint = _EncodeVarint
|
||||
def EncodePackedField(write, value):
|
||||
def EncodePackedField(write, value, deterministic):
|
||||
write(tag_bytes)
|
||||
local_EncodeVarint(write, len(value) * value_size)
|
||||
local_EncodeVarint(write, len(value) * value_size, deterministic)
|
||||
for element in value:
|
||||
write(local_struct_pack(format, element))
|
||||
return EncodePackedField
|
||||
elif is_repeated:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, unused_deterministic):
|
||||
for element in value:
|
||||
write(tag_bytes)
|
||||
write(local_struct_pack(format, element))
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, unused_deterministic):
|
||||
write(tag_bytes)
|
||||
return write(local_struct_pack(format, value))
|
||||
return EncodeField
|
||||
@ -581,9 +581,9 @@ def _FloatingPointEncoder(wire_type, format):
|
||||
if is_packed:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
|
||||
local_EncodeVarint = _EncodeVarint
|
||||
def EncodePackedField(write, value):
|
||||
def EncodePackedField(write, value, deterministic):
|
||||
write(tag_bytes)
|
||||
local_EncodeVarint(write, len(value) * value_size)
|
||||
local_EncodeVarint(write, len(value) * value_size, deterministic)
|
||||
for element in value:
|
||||
# This try/except block is going to be faster than any code that
|
||||
# we could write to check whether element is finite.
|
||||
@ -594,7 +594,7 @@ def _FloatingPointEncoder(wire_type, format):
|
||||
return EncodePackedField
|
||||
elif is_repeated:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, unused_deterministic):
|
||||
for element in value:
|
||||
write(tag_bytes)
|
||||
try:
|
||||
@ -604,7 +604,7 @@ def _FloatingPointEncoder(wire_type, format):
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
tag_bytes = TagBytes(field_number, wire_type)
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, unused_deterministic):
|
||||
write(tag_bytes)
|
||||
try:
|
||||
write(local_struct_pack(format, value))
|
||||
@ -650,9 +650,9 @@ def BoolEncoder(field_number, is_repeated, is_packed):
|
||||
if is_packed:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_LENGTH_DELIMITED)
|
||||
local_EncodeVarint = _EncodeVarint
|
||||
def EncodePackedField(write, value):
|
||||
def EncodePackedField(write, value, deterministic):
|
||||
write(tag_bytes)
|
||||
local_EncodeVarint(write, len(value))
|
||||
local_EncodeVarint(write, len(value), deterministic)
|
||||
for element in value:
|
||||
if element:
|
||||
write(true_byte)
|
||||
@ -661,7 +661,7 @@ def BoolEncoder(field_number, is_repeated, is_packed):
|
||||
return EncodePackedField
|
||||
elif is_repeated:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, unused_deterministic):
|
||||
for element in value:
|
||||
write(tag_bytes)
|
||||
if element:
|
||||
@ -671,7 +671,7 @@ def BoolEncoder(field_number, is_repeated, is_packed):
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
tag_bytes = TagBytes(field_number, wire_format.WIRETYPE_VARINT)
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, unused_deterministic):
|
||||
write(tag_bytes)
|
||||
if value:
|
||||
return write(true_byte)
|
||||
@ -687,18 +687,18 @@ def StringEncoder(field_number, is_repeated, is_packed):
|
||||
local_len = len
|
||||
assert not is_packed
|
||||
if is_repeated:
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, deterministic):
|
||||
for element in value:
|
||||
encoded = element.encode('utf-8')
|
||||
write(tag)
|
||||
local_EncodeVarint(write, local_len(encoded))
|
||||
local_EncodeVarint(write, local_len(encoded), deterministic)
|
||||
write(encoded)
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, deterministic):
|
||||
encoded = value.encode('utf-8')
|
||||
write(tag)
|
||||
local_EncodeVarint(write, local_len(encoded))
|
||||
local_EncodeVarint(write, local_len(encoded), deterministic)
|
||||
return write(encoded)
|
||||
return EncodeField
|
||||
|
||||
@ -711,16 +711,16 @@ def BytesEncoder(field_number, is_repeated, is_packed):
|
||||
local_len = len
|
||||
assert not is_packed
|
||||
if is_repeated:
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, deterministic):
|
||||
for element in value:
|
||||
write(tag)
|
||||
local_EncodeVarint(write, local_len(element))
|
||||
local_EncodeVarint(write, local_len(element), deterministic)
|
||||
write(element)
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, deterministic):
|
||||
write(tag)
|
||||
local_EncodeVarint(write, local_len(value))
|
||||
local_EncodeVarint(write, local_len(value), deterministic)
|
||||
return write(value)
|
||||
return EncodeField
|
||||
|
||||
@ -732,16 +732,16 @@ def GroupEncoder(field_number, is_repeated, is_packed):
|
||||
end_tag = TagBytes(field_number, wire_format.WIRETYPE_END_GROUP)
|
||||
assert not is_packed
|
||||
if is_repeated:
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, deterministic):
|
||||
for element in value:
|
||||
write(start_tag)
|
||||
element._InternalSerialize(write)
|
||||
element._InternalSerialize(write, deterministic)
|
||||
write(end_tag)
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, deterministic):
|
||||
write(start_tag)
|
||||
value._InternalSerialize(write)
|
||||
value._InternalSerialize(write, deterministic)
|
||||
return write(end_tag)
|
||||
return EncodeField
|
||||
|
||||
@ -753,17 +753,17 @@ def MessageEncoder(field_number, is_repeated, is_packed):
|
||||
local_EncodeVarint = _EncodeVarint
|
||||
assert not is_packed
|
||||
if is_repeated:
|
||||
def EncodeRepeatedField(write, value):
|
||||
def EncodeRepeatedField(write, value, deterministic):
|
||||
for element in value:
|
||||
write(tag)
|
||||
local_EncodeVarint(write, element.ByteSize())
|
||||
element._InternalSerialize(write)
|
||||
local_EncodeVarint(write, element.ByteSize(), deterministic)
|
||||
element._InternalSerialize(write, deterministic)
|
||||
return EncodeRepeatedField
|
||||
else:
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, deterministic):
|
||||
write(tag)
|
||||
local_EncodeVarint(write, value.ByteSize())
|
||||
return value._InternalSerialize(write)
|
||||
local_EncodeVarint(write, value.ByteSize(), deterministic)
|
||||
return value._InternalSerialize(write, deterministic)
|
||||
return EncodeField
|
||||
|
||||
|
||||
@ -790,10 +790,10 @@ def MessageSetItemEncoder(field_number):
|
||||
end_bytes = TagBytes(1, wire_format.WIRETYPE_END_GROUP)
|
||||
local_EncodeVarint = _EncodeVarint
|
||||
|
||||
def EncodeField(write, value):
|
||||
def EncodeField(write, value, deterministic):
|
||||
write(start_bytes)
|
||||
local_EncodeVarint(write, value.ByteSize())
|
||||
value._InternalSerialize(write)
|
||||
local_EncodeVarint(write, value.ByteSize(), deterministic)
|
||||
value._InternalSerialize(write, deterministic)
|
||||
return write(end_bytes)
|
||||
|
||||
return EncodeField
|
||||
@ -818,9 +818,10 @@ def MapEncoder(field_descriptor):
|
||||
message_type = field_descriptor.message_type
|
||||
encode_message = MessageEncoder(field_descriptor.number, False, False)
|
||||
|
||||
def EncodeField(write, value):
|
||||
for key in value:
|
||||
def EncodeField(write, value, deterministic):
|
||||
value_keys = sorted(value.iterkeys()) if deterministic else value.iterkeys()
|
||||
for key in value_keys:
|
||||
entry_msg = message_type._concrete_class(key=key, value=value[key])
|
||||
encode_message(write, entry_msg)
|
||||
encode_message(write, entry_msg, deterministic)
|
||||
|
||||
return EncodeField
|
||||
|
@ -97,3 +97,8 @@ message MessageWithNestedEnumOnly {
|
||||
extend Factory1Message {
|
||||
optional string another_field = 1002;
|
||||
}
|
||||
|
||||
message MessageWithOption {
|
||||
option no_standard_descriptor_accessor = true;
|
||||
optional int32 field1 = 1;
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ from google.protobuf import field_mask_pb2
|
||||
from google.protobuf import struct_pb2
|
||||
from google.protobuf import timestamp_pb2
|
||||
from google.protobuf import wrappers_pb2
|
||||
from google.protobuf import unittest_mset_pb2
|
||||
from google.protobuf.internal import well_known_types
|
||||
from google.protobuf import json_format
|
||||
from google.protobuf.util import json_format_proto3_pb2
|
||||
@ -158,6 +159,84 @@ class JsonFormatTest(JsonFormatBase):
|
||||
json_format.Parse(text, parsed_message)
|
||||
self.assertEqual(message, parsed_message)
|
||||
|
||||
def testExtensionToJsonAndBack(self):
|
||||
message = unittest_mset_pb2.TestMessageSetContainer()
|
||||
ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
|
||||
ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
|
||||
message.message_set.Extensions[ext1].i = 23
|
||||
message.message_set.Extensions[ext2].str = 'foo'
|
||||
message_text = json_format.MessageToJson(
|
||||
message
|
||||
)
|
||||
parsed_message = unittest_mset_pb2.TestMessageSetContainer()
|
||||
json_format.Parse(message_text, parsed_message)
|
||||
self.assertEqual(message, parsed_message)
|
||||
|
||||
def testExtensionToDictAndBack(self):
|
||||
message = unittest_mset_pb2.TestMessageSetContainer()
|
||||
ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
|
||||
ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
|
||||
message.message_set.Extensions[ext1].i = 23
|
||||
message.message_set.Extensions[ext2].str = 'foo'
|
||||
message_dict = json_format.MessageToDict(
|
||||
message
|
||||
)
|
||||
parsed_message = unittest_mset_pb2.TestMessageSetContainer()
|
||||
json_format.ParseDict(message_dict, parsed_message)
|
||||
self.assertEqual(message, parsed_message)
|
||||
|
||||
def testExtensionSerializationDictMatchesProto3Spec(self):
|
||||
"""See go/proto3-json-spec for spec.
|
||||
"""
|
||||
message = unittest_mset_pb2.TestMessageSetContainer()
|
||||
ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
|
||||
ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
|
||||
message.message_set.Extensions[ext1].i = 23
|
||||
message.message_set.Extensions[ext2].str = 'foo'
|
||||
message_dict = json_format.MessageToDict(
|
||||
message
|
||||
)
|
||||
golden_dict = {
|
||||
'messageSet': {
|
||||
'[protobuf_unittest.'
|
||||
'TestMessageSetExtension1.messageSetExtension]': {
|
||||
'i': 23,
|
||||
},
|
||||
'[protobuf_unittest.'
|
||||
'TestMessageSetExtension2.messageSetExtension]': {
|
||||
'str': u'foo',
|
||||
},
|
||||
},
|
||||
}
|
||||
self.assertEqual(golden_dict, message_dict)
|
||||
|
||||
|
||||
def testExtensionSerializationJsonMatchesProto3Spec(self):
|
||||
"""See go/proto3-json-spec for spec.
|
||||
"""
|
||||
message = unittest_mset_pb2.TestMessageSetContainer()
|
||||
ext1 = unittest_mset_pb2.TestMessageSetExtension1.message_set_extension
|
||||
ext2 = unittest_mset_pb2.TestMessageSetExtension2.message_set_extension
|
||||
message.message_set.Extensions[ext1].i = 23
|
||||
message.message_set.Extensions[ext2].str = 'foo'
|
||||
message_text = json_format.MessageToJson(
|
||||
message
|
||||
)
|
||||
ext1_text = ('protobuf_unittest.TestMessageSetExtension1.'
|
||||
'messageSetExtension')
|
||||
ext2_text = ('protobuf_unittest.TestMessageSetExtension2.'
|
||||
'messageSetExtension')
|
||||
golden_text = ('{"messageSet": {'
|
||||
' "[%s]": {'
|
||||
' "i": 23'
|
||||
' },'
|
||||
' "[%s]": {'
|
||||
' "str": "foo"'
|
||||
' }'
|
||||
'}}') % (ext1_text, ext2_text)
|
||||
self.assertEqual(json.loads(golden_text), json.loads(message_text))
|
||||
|
||||
|
||||
def testJsonEscapeString(self):
|
||||
message = json_format_proto3_pb2.TestMessage()
|
||||
if sys.version_info[0] < 3:
|
||||
@ -768,7 +847,7 @@ class JsonFormatTest(JsonFormatBase):
|
||||
text = '{"value": "0000-01-01T00:00:00Z"}'
|
||||
self.assertRaisesRegexp(
|
||||
json_format.ParseError,
|
||||
'Failed to parse value field: year is out of range.',
|
||||
'Failed to parse value field: year (0 )?is out of range.',
|
||||
json_format.Parse, text, message)
|
||||
# Time bigger than maxinum time.
|
||||
message.value.seconds = 253402300800
|
||||
@ -840,6 +919,12 @@ class JsonFormatTest(JsonFormatBase):
|
||||
json_format.Parse('{"int32_value": 12345}', message)
|
||||
self.assertEqual(12345, message.int32_value)
|
||||
|
||||
def testIndent(self):
|
||||
message = json_format_proto3_pb2.TestMessage()
|
||||
message.int32_value = 12345
|
||||
self.assertEqual('{\n"int32Value": 12345\n}',
|
||||
json_format.MessageToJson(message, indent=0))
|
||||
|
||||
def testParseDict(self):
|
||||
expected = 12345
|
||||
js_dict = {'int32Value': expected}
|
||||
@ -862,6 +947,22 @@ class JsonFormatTest(JsonFormatBase):
|
||||
parsed_message = json_format_proto3_pb2.TestCustomJsonName()
|
||||
self.CheckParseBack(message, parsed_message)
|
||||
|
||||
def testSortKeys(self):
|
||||
# Testing sort_keys is not perfectly working, as by random luck we could
|
||||
# get the output sorted. We just use a selection of names.
|
||||
message = json_format_proto3_pb2.TestMessage(bool_value=True,
|
||||
int32_value=1,
|
||||
int64_value=3,
|
||||
uint32_value=4,
|
||||
string_value='bla')
|
||||
self.assertEqual(
|
||||
json_format.MessageToJson(message, sort_keys=True),
|
||||
# We use json.dumps() instead of a hardcoded string due to differences
|
||||
# between Python 2 and Python 3.
|
||||
json.dumps({'boolValue': True, 'int32Value': 1, 'int64Value': '3',
|
||||
'uint32Value': 4, 'stringValue': 'bla'},
|
||||
indent=2, sort_keys=True))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -136,6 +136,39 @@ class MessageTest(BaseTestCase):
|
||||
golden_copy = copy.deepcopy(golden_message)
|
||||
self.assertEqual(golden_data, golden_copy.SerializeToString())
|
||||
|
||||
def testDeterminismParameters(self, message_module):
|
||||
# This message is always deterministically serialized, even if determinism
|
||||
# is disabled, so we can use it to verify that all the determinism
|
||||
# parameters work correctly.
|
||||
golden_data = (b'\xe2\x02\nOne string'
|
||||
b'\xe2\x02\nTwo string'
|
||||
b'\xe2\x02\nRed string'
|
||||
b'\xe2\x02\x0bBlue string')
|
||||
golden_message = message_module.TestAllTypes()
|
||||
golden_message.repeated_string.extend([
|
||||
'One string',
|
||||
'Two string',
|
||||
'Red string',
|
||||
'Blue string',
|
||||
])
|
||||
self.assertEqual(golden_data,
|
||||
golden_message.SerializeToString(deterministic=None))
|
||||
self.assertEqual(golden_data,
|
||||
golden_message.SerializeToString(deterministic=False))
|
||||
self.assertEqual(golden_data,
|
||||
golden_message.SerializeToString(deterministic=True))
|
||||
|
||||
class BadArgError(Exception):
|
||||
pass
|
||||
|
||||
class BadArg(object):
|
||||
|
||||
def __nonzero__(self):
|
||||
raise BadArgError()
|
||||
|
||||
with self.assertRaises(BadArgError):
|
||||
golden_message.SerializeToString(deterministic=BadArg())
|
||||
|
||||
def testPickleSupport(self, message_module):
|
||||
golden_data = test_util.GoldenFileData('golden_message')
|
||||
golden_message = message_module.TestAllTypes()
|
||||
@ -377,6 +410,7 @@ class MessageTest(BaseTestCase):
|
||||
self.assertEqual(message.repeated_int32[0], 1)
|
||||
self.assertEqual(message.repeated_int32[1], 2)
|
||||
self.assertEqual(message.repeated_int32[2], 3)
|
||||
self.assertEqual(str(message.repeated_int32), str([1, 2, 3]))
|
||||
|
||||
message.repeated_float.append(1.1)
|
||||
message.repeated_float.append(1.3)
|
||||
@ -393,6 +427,7 @@ class MessageTest(BaseTestCase):
|
||||
self.assertEqual(message.repeated_string[0], 'a')
|
||||
self.assertEqual(message.repeated_string[1], 'b')
|
||||
self.assertEqual(message.repeated_string[2], 'c')
|
||||
self.assertEqual(str(message.repeated_string), str([u'a', u'b', u'c']))
|
||||
|
||||
message.repeated_bytes.append(b'a')
|
||||
message.repeated_bytes.append(b'c')
|
||||
@ -401,6 +436,7 @@ class MessageTest(BaseTestCase):
|
||||
self.assertEqual(message.repeated_bytes[0], b'a')
|
||||
self.assertEqual(message.repeated_bytes[1], b'b')
|
||||
self.assertEqual(message.repeated_bytes[2], b'c')
|
||||
self.assertEqual(str(message.repeated_bytes), str([b'a', b'b', b'c']))
|
||||
|
||||
def testSortingRepeatedScalarFieldsCustomComparator(self, message_module):
|
||||
"""Check some different types with custom comparator."""
|
||||
@ -439,6 +475,8 @@ class MessageTest(BaseTestCase):
|
||||
self.assertEqual(message.repeated_nested_message[3].bb, 4)
|
||||
self.assertEqual(message.repeated_nested_message[4].bb, 5)
|
||||
self.assertEqual(message.repeated_nested_message[5].bb, 6)
|
||||
self.assertEqual(str(message.repeated_nested_message),
|
||||
'[bb: 1\n, bb: 2\n, bb: 3\n, bb: 4\n, bb: 5\n, bb: 6\n]')
|
||||
|
||||
def testSortingRepeatedCompositeFieldsStable(self, message_module):
|
||||
"""Check passing a custom comparator to sort a repeated composite field."""
|
||||
@ -1266,6 +1304,14 @@ class Proto3Test(BaseTestCase):
|
||||
self.assertEqual(1234567, m2.optional_nested_enum)
|
||||
self.assertEqual(7654321, m2.repeated_nested_enum[0])
|
||||
|
||||
# ParseFromString in Proto2 should accept unknown enums too.
|
||||
m3 = unittest_pb2.TestAllTypes()
|
||||
m3.ParseFromString(serialized)
|
||||
m2.Clear()
|
||||
m2.ParseFromString(m3.SerializeToString())
|
||||
self.assertEqual(1234567, m2.optional_nested_enum)
|
||||
self.assertEqual(7654321, m2.repeated_nested_enum[0])
|
||||
|
||||
# Map isn't really a proto3-only feature. But there is no proto2 equivalent
|
||||
# of google/protobuf/map_unittest.proto right now, so it's not easy to
|
||||
# test both with the same test like we do for the other proto2/proto3 tests.
|
||||
@ -1437,6 +1483,23 @@ class Proto3Test(BaseTestCase):
|
||||
self.assertIn(-456, msg2.map_int32_foreign_message)
|
||||
self.assertEqual(2, len(msg2.map_int32_foreign_message))
|
||||
|
||||
def testNestedMessageMapItemDelete(self):
|
||||
msg = map_unittest_pb2.TestMap()
|
||||
msg.map_int32_all_types[1].optional_nested_message.bb = 1
|
||||
del msg.map_int32_all_types[1]
|
||||
msg.map_int32_all_types[2].optional_nested_message.bb = 2
|
||||
self.assertEqual(1, len(msg.map_int32_all_types))
|
||||
msg.map_int32_all_types[1].optional_nested_message.bb = 1
|
||||
self.assertEqual(2, len(msg.map_int32_all_types))
|
||||
|
||||
serialized = msg.SerializeToString()
|
||||
msg2 = map_unittest_pb2.TestMap()
|
||||
msg2.ParseFromString(serialized)
|
||||
keys = [1, 2]
|
||||
# The loop triggers PyErr_Occurred() in c extension.
|
||||
for key in keys:
|
||||
del msg2.map_int32_all_types[key]
|
||||
|
||||
def testMapByteSize(self):
|
||||
msg = map_unittest_pb2.TestMap()
|
||||
msg.map_int32_int32[1] = 1
|
||||
@ -1651,6 +1714,35 @@ class Proto3Test(BaseTestCase):
|
||||
items2 = msg.map_string_string.items()
|
||||
self.assertEqual(items1, items2)
|
||||
|
||||
def testMapDeterministicSerialization(self):
|
||||
golden_data = (b'r\x0c\n\x07init_op\x12\x01d'
|
||||
b'r\n\n\x05item1\x12\x01e'
|
||||
b'r\n\n\x05item2\x12\x01f'
|
||||
b'r\n\n\x05item3\x12\x01g'
|
||||
b'r\x0b\n\x05item4\x12\x02QQ'
|
||||
b'r\x12\n\rlocal_init_op\x12\x01a'
|
||||
b'r\x0e\n\tsummaries\x12\x01e'
|
||||
b'r\x18\n\x13trainable_variables\x12\x01b'
|
||||
b'r\x0e\n\tvariables\x12\x01c')
|
||||
msg = map_unittest_pb2.TestMap()
|
||||
msg.map_string_string['local_init_op'] = 'a'
|
||||
msg.map_string_string['trainable_variables'] = 'b'
|
||||
msg.map_string_string['variables'] = 'c'
|
||||
msg.map_string_string['init_op'] = 'd'
|
||||
msg.map_string_string['summaries'] = 'e'
|
||||
msg.map_string_string['item1'] = 'e'
|
||||
msg.map_string_string['item2'] = 'f'
|
||||
msg.map_string_string['item3'] = 'g'
|
||||
msg.map_string_string['item4'] = 'QQ'
|
||||
|
||||
# If deterministic serialization is not working correctly, this will be
|
||||
# "flaky" depending on the exact python dict hash seed.
|
||||
#
|
||||
# Fortunately, there are enough items in this map that it is extremely
|
||||
# unlikely to ever hit the "right" in-order combination, so the test
|
||||
# itself should fail reliably.
|
||||
self.assertEqual(golden_data, msg.SerializeToString(deterministic=True))
|
||||
|
||||
def testMapIterationClearMessage(self):
|
||||
# Iterator needs to work even if message and map are deleted.
|
||||
msg = map_unittest_pb2.TestMap()
|
||||
|
@ -47,4 +47,5 @@ message DynamicMessageType {
|
||||
extend ExtendedMessage {
|
||||
optional int32 dynamic_int32_extension = 100;
|
||||
optional DynamicMessageType dynamic_message_extension = 101;
|
||||
repeated DynamicMessageType repeated_dynamic_message_extension = 102;
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ import weakref
|
||||
import six
|
||||
|
||||
# We use "as" to avoid name collisions with variables.
|
||||
from google.protobuf.internal import api_implementation
|
||||
from google.protobuf.internal import containers
|
||||
from google.protobuf.internal import decoder
|
||||
from google.protobuf.internal import encoder
|
||||
@ -1026,29 +1027,34 @@ def _AddByteSizeMethod(message_descriptor, cls):
|
||||
def _AddSerializeToStringMethod(message_descriptor, cls):
|
||||
"""Helper for _AddMessageMethods()."""
|
||||
|
||||
def SerializeToString(self):
|
||||
def SerializeToString(self, **kwargs):
|
||||
# Check if the message has all of its required fields set.
|
||||
errors = []
|
||||
if not self.IsInitialized():
|
||||
raise message_mod.EncodeError(
|
||||
'Message %s is missing required fields: %s' % (
|
||||
self.DESCRIPTOR.full_name, ','.join(self.FindInitializationErrors())))
|
||||
return self.SerializePartialToString()
|
||||
return self.SerializePartialToString(**kwargs)
|
||||
cls.SerializeToString = SerializeToString
|
||||
|
||||
|
||||
def _AddSerializePartialToStringMethod(message_descriptor, cls):
|
||||
"""Helper for _AddMessageMethods()."""
|
||||
|
||||
def SerializePartialToString(self):
|
||||
def SerializePartialToString(self, **kwargs):
|
||||
out = BytesIO()
|
||||
self._InternalSerialize(out.write)
|
||||
self._InternalSerialize(out.write, **kwargs)
|
||||
return out.getvalue()
|
||||
cls.SerializePartialToString = SerializePartialToString
|
||||
|
||||
def InternalSerialize(self, write_bytes):
|
||||
def InternalSerialize(self, write_bytes, deterministic=None):
|
||||
if deterministic is None:
|
||||
deterministic = (
|
||||
api_implementation.IsPythonDefaultSerializationDeterministic())
|
||||
else:
|
||||
deterministic = bool(deterministic)
|
||||
for field_descriptor, field_value in self.ListFields():
|
||||
field_descriptor._encoder(write_bytes, field_value)
|
||||
field_descriptor._encoder(write_bytes, field_value, deterministic)
|
||||
for tag_bytes, value_bytes in self._unknown_fields:
|
||||
write_bytes(tag_bytes)
|
||||
write_bytes(value_bytes)
|
||||
|
@ -452,16 +452,18 @@ class TextFormatTest(TextFormatBase):
|
||||
text_format.Parse(text_format.MessageToString(m), m2)
|
||||
self.assertEqual('oneof_uint32', m2.WhichOneof('oneof_field'))
|
||||
|
||||
def testMergeMultipleOneof(self, message_module):
|
||||
m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"'])
|
||||
m2 = message_module.TestAllTypes()
|
||||
text_format.Merge(m_string, m2)
|
||||
self.assertEqual('oneof_string', m2.WhichOneof('oneof_field'))
|
||||
|
||||
def testParseMultipleOneof(self, message_module):
|
||||
m_string = '\n'.join(['oneof_uint32: 11', 'oneof_string: "foo"'])
|
||||
m2 = message_module.TestAllTypes()
|
||||
if message_module is unittest_pb2:
|
||||
with self.assertRaisesRegexp(text_format.ParseError,
|
||||
' is specified along with field '):
|
||||
text_format.Parse(m_string, m2)
|
||||
else:
|
||||
with self.assertRaisesRegexp(text_format.ParseError,
|
||||
' is specified along with field '):
|
||||
text_format.Parse(m_string, m2)
|
||||
self.assertEqual('oneof_string', m2.WhichOneof('oneof_field'))
|
||||
|
||||
|
||||
# These are tests that aren't fundamentally specific to proto2, but are at
|
||||
@ -1026,8 +1028,7 @@ class Proto3Tests(unittest.TestCase):
|
||||
packed_message.data = 'string1'
|
||||
message.repeated_any_value.add().Pack(packed_message)
|
||||
self.assertEqual(
|
||||
text_format.MessageToString(message,
|
||||
descriptor_pool=descriptor_pool.Default()),
|
||||
text_format.MessageToString(message),
|
||||
'repeated_any_value {\n'
|
||||
' [type.googleapis.com/protobuf_unittest.OneString] {\n'
|
||||
' data: "string0"\n'
|
||||
@ -1039,18 +1040,6 @@ class Proto3Tests(unittest.TestCase):
|
||||
' }\n'
|
||||
'}\n')
|
||||
|
||||
def testPrintMessageExpandAnyNoDescriptorPool(self):
|
||||
packed_message = unittest_pb2.OneString()
|
||||
packed_message.data = 'string'
|
||||
message = any_test_pb2.TestAny()
|
||||
message.any_value.Pack(packed_message)
|
||||
self.assertEqual(
|
||||
text_format.MessageToString(message, descriptor_pool=None),
|
||||
'any_value {\n'
|
||||
' type_url: "type.googleapis.com/protobuf_unittest.OneString"\n'
|
||||
' value: "\\n\\006string"\n'
|
||||
'}\n')
|
||||
|
||||
def testPrintMessageExpandAnyDescriptorPoolMissingType(self):
|
||||
packed_message = unittest_pb2.OneString()
|
||||
packed_message.data = 'string'
|
||||
@ -1071,8 +1060,7 @@ class Proto3Tests(unittest.TestCase):
|
||||
message.any_value.Pack(packed_message)
|
||||
self.assertEqual(
|
||||
text_format.MessageToString(message,
|
||||
pointy_brackets=True,
|
||||
descriptor_pool=descriptor_pool.Default()),
|
||||
pointy_brackets=True),
|
||||
'any_value <\n'
|
||||
' [type.googleapis.com/protobuf_unittest.OneString] <\n'
|
||||
' data: "string"\n'
|
||||
@ -1086,8 +1074,7 @@ class Proto3Tests(unittest.TestCase):
|
||||
message.any_value.Pack(packed_message)
|
||||
self.assertEqual(
|
||||
text_format.MessageToString(message,
|
||||
as_one_line=True,
|
||||
descriptor_pool=descriptor_pool.Default()),
|
||||
as_one_line=True),
|
||||
'any_value {'
|
||||
' [type.googleapis.com/protobuf_unittest.OneString]'
|
||||
' { data: "string" } '
|
||||
@ -1115,12 +1102,12 @@ class Proto3Tests(unittest.TestCase):
|
||||
' data: "string"\n'
|
||||
' }\n'
|
||||
'}\n')
|
||||
text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
|
||||
text_format.Merge(text, message)
|
||||
packed_message = unittest_pb2.OneString()
|
||||
message.any_value.Unpack(packed_message)
|
||||
self.assertEqual('string', packed_message.data)
|
||||
message.Clear()
|
||||
text_format.Parse(text, message, descriptor_pool=descriptor_pool.Default())
|
||||
text_format.Parse(text, message)
|
||||
packed_message = unittest_pb2.OneString()
|
||||
message.any_value.Unpack(packed_message)
|
||||
self.assertEqual('string', packed_message.data)
|
||||
@ -1137,7 +1124,7 @@ class Proto3Tests(unittest.TestCase):
|
||||
' data: "string1"\n'
|
||||
' }\n'
|
||||
'}\n')
|
||||
text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
|
||||
text_format.Merge(text, message)
|
||||
packed_message = unittest_pb2.OneString()
|
||||
message.repeated_any_value[0].Unpack(packed_message)
|
||||
self.assertEqual('string0', packed_message.data)
|
||||
@ -1151,22 +1138,22 @@ class Proto3Tests(unittest.TestCase):
|
||||
' data: "string"\n'
|
||||
' >\n'
|
||||
'}\n')
|
||||
text_format.Merge(text, message, descriptor_pool=descriptor_pool.Default())
|
||||
text_format.Merge(text, message)
|
||||
packed_message = unittest_pb2.OneString()
|
||||
message.any_value.Unpack(packed_message)
|
||||
self.assertEqual('string', packed_message.data)
|
||||
|
||||
def testMergeExpandedAnyNoDescriptorPool(self):
|
||||
def testMergeAlternativeUrl(self):
|
||||
message = any_test_pb2.TestAny()
|
||||
text = ('any_value {\n'
|
||||
' [type.googleapis.com/protobuf_unittest.OneString] {\n'
|
||||
' [type.otherapi.com/protobuf_unittest.OneString] {\n'
|
||||
' data: "string"\n'
|
||||
' }\n'
|
||||
'}\n')
|
||||
with self.assertRaises(text_format.ParseError) as e:
|
||||
text_format.Merge(text, message, descriptor_pool=None)
|
||||
self.assertEqual(str(e.exception),
|
||||
'Descriptor pool required to parse expanded Any field')
|
||||
text_format.Merge(text, message)
|
||||
packed_message = unittest_pb2.OneString()
|
||||
self.assertEqual('type.otherapi.com/protobuf_unittest.OneString',
|
||||
message.any_value.type_url)
|
||||
|
||||
def testMergeExpandedAnyDescriptorPoolMissingType(self):
|
||||
message = any_test_pb2.TestAny()
|
||||
@ -1425,5 +1412,101 @@ class TokenizerTest(unittest.TestCase):
|
||||
tokenizer.ConsumeCommentOrTrailingComment())
|
||||
self.assertTrue(tokenizer.AtEnd())
|
||||
|
||||
|
||||
# Tests for pretty printer functionality.
|
||||
@_parameterized.Parameters((unittest_pb2), (unittest_proto3_arena_pb2))
|
||||
class PrettyPrinterTest(TextFormatBase):
|
||||
|
||||
def testPrettyPrintNoMatch(self, message_module):
|
||||
|
||||
def printer(message, indent, as_one_line):
|
||||
del message, indent, as_one_line
|
||||
return None
|
||||
|
||||
message = message_module.TestAllTypes()
|
||||
msg = message.repeated_nested_message.add()
|
||||
msg.bb = 42
|
||||
self.CompareToGoldenText(
|
||||
text_format.MessageToString(
|
||||
message, as_one_line=True, message_formatter=printer),
|
||||
'repeated_nested_message { bb: 42 }')
|
||||
|
||||
def testPrettyPrintOneLine(self, message_module):
|
||||
|
||||
def printer(m, indent, as_one_line):
|
||||
del indent, as_one_line
|
||||
if m.DESCRIPTOR == message_module.TestAllTypes.NestedMessage.DESCRIPTOR:
|
||||
return 'My lucky number is %s' % m.bb
|
||||
|
||||
message = message_module.TestAllTypes()
|
||||
msg = message.repeated_nested_message.add()
|
||||
msg.bb = 42
|
||||
self.CompareToGoldenText(
|
||||
text_format.MessageToString(
|
||||
message, as_one_line=True, message_formatter=printer),
|
||||
'repeated_nested_message { My lucky number is 42 }')
|
||||
|
||||
def testPrettyPrintMultiLine(self, message_module):
|
||||
|
||||
def printer(m, indent, as_one_line):
|
||||
if m.DESCRIPTOR == message_module.TestAllTypes.NestedMessage.DESCRIPTOR:
|
||||
line_deliminator = (' ' if as_one_line else '\n') + ' ' * indent
|
||||
return 'My lucky number is:%s%s' % (line_deliminator, m.bb)
|
||||
return None
|
||||
|
||||
message = message_module.TestAllTypes()
|
||||
msg = message.repeated_nested_message.add()
|
||||
msg.bb = 42
|
||||
self.CompareToGoldenText(
|
||||
text_format.MessageToString(
|
||||
message, as_one_line=True, message_formatter=printer),
|
||||
'repeated_nested_message { My lucky number is: 42 }')
|
||||
self.CompareToGoldenText(
|
||||
text_format.MessageToString(
|
||||
message, as_one_line=False, message_formatter=printer),
|
||||
'repeated_nested_message {\n My lucky number is:\n 42\n}\n')
|
||||
|
||||
def testPrettyPrintEntireMessage(self, message_module):
|
||||
|
||||
def printer(m, indent, as_one_line):
|
||||
del indent, as_one_line
|
||||
if m.DESCRIPTOR == message_module.TestAllTypes.DESCRIPTOR:
|
||||
return 'The is the message!'
|
||||
return None
|
||||
|
||||
message = message_module.TestAllTypes()
|
||||
self.CompareToGoldenText(
|
||||
text_format.MessageToString(
|
||||
message, as_one_line=False, message_formatter=printer),
|
||||
'The is the message!\n')
|
||||
self.CompareToGoldenText(
|
||||
text_format.MessageToString(
|
||||
message, as_one_line=True, message_formatter=printer),
|
||||
'The is the message!')
|
||||
|
||||
def testPrettyPrintMultipleParts(self, message_module):
|
||||
|
||||
def printer(m, indent, as_one_line):
|
||||
del indent, as_one_line
|
||||
if m.DESCRIPTOR == message_module.TestAllTypes.NestedMessage.DESCRIPTOR:
|
||||
return 'My lucky number is %s' % m.bb
|
||||
return None
|
||||
|
||||
message = message_module.TestAllTypes()
|
||||
message.optional_int32 = 61
|
||||
msg = message.repeated_nested_message.add()
|
||||
msg.bb = 42
|
||||
msg = message.repeated_nested_message.add()
|
||||
msg.bb = 99
|
||||
msg = message.optional_nested_message
|
||||
msg.bb = 1
|
||||
self.CompareToGoldenText(
|
||||
text_format.MessageToString(
|
||||
message, as_one_line=True, message_formatter=printer),
|
||||
('optional_int32: 61 '
|
||||
'optional_nested_message { My lucky number is 1 } '
|
||||
'repeated_nested_message { My lucky number is 42 } '
|
||||
'repeated_nested_message { My lucky number is 99 }'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -350,12 +350,12 @@ class Duration(object):
|
||||
self.nanos, _NANOS_PER_MICROSECOND))
|
||||
|
||||
def FromTimedelta(self, td):
|
||||
"""Convertd timedelta to Duration."""
|
||||
"""Converts timedelta to Duration."""
|
||||
self._NormalizeDuration(td.seconds + td.days * _SECONDS_PER_DAY,
|
||||
td.microseconds * _NANOS_PER_MICROSECOND)
|
||||
|
||||
def _NormalizeDuration(self, seconds, nanos):
|
||||
"""Set Duration by seconds and nonas."""
|
||||
"""Set Duration by seconds and nanos."""
|
||||
# Force nanos to be negative if the duration is negative.
|
||||
if seconds < 0 and nanos > 0:
|
||||
seconds += 1
|
||||
|
@ -284,7 +284,7 @@ class TimeUtilTest(TimeUtilTestBase):
|
||||
'1972-01-01T01:00:00.01+08',)
|
||||
self.assertRaisesRegexp(
|
||||
ValueError,
|
||||
'year is out of range',
|
||||
'year (0 )?is out of range',
|
||||
message.FromJsonString,
|
||||
'0000-01-01T00:00:00Z')
|
||||
message.seconds = 253402300800
|
||||
|
@ -74,6 +74,9 @@ _UNPAIRED_SURROGATE_PATTERN = re.compile(six.u(
|
||||
r'[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]'
|
||||
))
|
||||
|
||||
_VALID_EXTENSION_NAME = re.compile(r'\[[a-zA-Z0-9\._]*\]$')
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
"""Top-level module error for json_format."""
|
||||
|
||||
@ -88,7 +91,9 @@ class ParseError(Error):
|
||||
|
||||
def MessageToJson(message,
|
||||
including_default_value_fields=False,
|
||||
preserving_proto_field_name=False):
|
||||
preserving_proto_field_name=False,
|
||||
indent=2,
|
||||
sort_keys=False):
|
||||
"""Converts protobuf message to JSON format.
|
||||
|
||||
Args:
|
||||
@ -100,19 +105,24 @@ def MessageToJson(message,
|
||||
preserving_proto_field_name: If True, use the original proto field
|
||||
names as defined in the .proto file. If False, convert the field
|
||||
names to lowerCamelCase.
|
||||
indent: The JSON object will be pretty-printed with this indent level.
|
||||
An indent level of 0 or negative will only insert newlines.
|
||||
sort_keys: If True, then the output will be sorted by field names.
|
||||
|
||||
Returns:
|
||||
A string containing the JSON formatted protocol buffer message.
|
||||
"""
|
||||
printer = _Printer(including_default_value_fields,
|
||||
preserving_proto_field_name)
|
||||
return printer.ToJsonString(message)
|
||||
return printer.ToJsonString(message, indent, sort_keys)
|
||||
|
||||
|
||||
def MessageToDict(message,
|
||||
including_default_value_fields=False,
|
||||
preserving_proto_field_name=False):
|
||||
"""Converts protobuf message to a JSON dictionary.
|
||||
"""Converts protobuf message to a dictionary.
|
||||
|
||||
When the dictionary is encoded to JSON, it conforms to proto3 JSON spec.
|
||||
|
||||
Args:
|
||||
message: The protocol buffers message instance to serialize.
|
||||
@ -125,7 +135,7 @@ def MessageToDict(message,
|
||||
names to lowerCamelCase.
|
||||
|
||||
Returns:
|
||||
A dict representation of the JSON formatted protocol buffer message.
|
||||
A dict representation of the protocol buffer message.
|
||||
"""
|
||||
printer = _Printer(including_default_value_fields,
|
||||
preserving_proto_field_name)
|
||||
@ -148,9 +158,9 @@ class _Printer(object):
|
||||
self.including_default_value_fields = including_default_value_fields
|
||||
self.preserving_proto_field_name = preserving_proto_field_name
|
||||
|
||||
def ToJsonString(self, message):
|
||||
def ToJsonString(self, message, indent, sort_keys):
|
||||
js = self._MessageToJsonObject(message)
|
||||
return json.dumps(js, indent=2)
|
||||
return json.dumps(js, indent=indent, sort_keys=sort_keys)
|
||||
|
||||
def _MessageToJsonObject(self, message):
|
||||
"""Converts message to an object according to Proto3 JSON Specification."""
|
||||
@ -192,6 +202,14 @@ class _Printer(object):
|
||||
# Convert a repeated field.
|
||||
js[name] = [self._FieldToJsonObject(field, k)
|
||||
for k in value]
|
||||
elif field.is_extension:
|
||||
f = field
|
||||
if (f.containing_type.GetOptions().message_set_wire_format and
|
||||
f.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
|
||||
f.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
|
||||
f = f.message_type
|
||||
name = '[%s.%s]' % (f.full_name, name)
|
||||
js[name] = self._FieldToJsonObject(field, value)
|
||||
else:
|
||||
js[name] = self._FieldToJsonObject(field, value)
|
||||
|
||||
@ -433,12 +451,23 @@ class _Parser(object):
|
||||
field = fields_by_json_name.get(name, None)
|
||||
if not field:
|
||||
field = message_descriptor.fields_by_name.get(name, None)
|
||||
if not field and _VALID_EXTENSION_NAME.match(name):
|
||||
if not message_descriptor.is_extendable:
|
||||
raise ParseError('Message type {0} does not have extensions'.format(
|
||||
message_descriptor.full_name))
|
||||
identifier = name[1:-1] # strip [] brackets
|
||||
identifier = '.'.join(identifier.split('.')[:-1])
|
||||
# pylint: disable=protected-access
|
||||
field = message.Extensions._FindExtensionByName(identifier)
|
||||
# pylint: enable=protected-access
|
||||
if not field:
|
||||
if self.ignore_unknown_fields:
|
||||
continue
|
||||
raise ParseError(
|
||||
'Message type "{0}" has no field named "{1}".'.format(
|
||||
message_descriptor.full_name, name))
|
||||
('Message type "{0}" has no field named "{1}".\n'
|
||||
' Available Fields(except extensions): {2}').format(
|
||||
message_descriptor.full_name, name,
|
||||
message_descriptor.fields))
|
||||
if name in names:
|
||||
raise ParseError('Message type "{0}" should not have multiple '
|
||||
'"{1}" fields.'.format(
|
||||
@ -491,7 +520,10 @@ class _Parser(object):
|
||||
getattr(message, field.name).append(
|
||||
_ConvertScalarFieldValue(item, field))
|
||||
elif field.cpp_type == descriptor.FieldDescriptor.CPPTYPE_MESSAGE:
|
||||
sub_message = getattr(message, field.name)
|
||||
if field.is_extension:
|
||||
sub_message = message.Extensions[field]
|
||||
else:
|
||||
sub_message = getattr(message, field.name)
|
||||
sub_message.SetInParent()
|
||||
self.ConvertMessage(value, sub_message)
|
||||
else:
|
||||
@ -532,8 +564,8 @@ class _Parser(object):
|
||||
|
||||
def _ConvertGenericMessage(self, value, message):
|
||||
"""Convert a JSON representation into message with FromJsonString."""
|
||||
# Durantion, Timestamp, FieldMask have FromJsonString method to do the
|
||||
# convert. Users can also call the method directly.
|
||||
# Duration, Timestamp, FieldMask have a FromJsonString method to do the
|
||||
# conversion. Users can also call the method directly.
|
||||
message.FromJsonString(value)
|
||||
|
||||
def _ConvertValueMessage(self, value, message):
|
||||
|
@ -184,9 +184,15 @@ class Message(object):
|
||||
self.Clear()
|
||||
self.MergeFromString(serialized)
|
||||
|
||||
def SerializeToString(self):
|
||||
def SerializeToString(self, **kwargs):
|
||||
"""Serializes the protocol message to a binary string.
|
||||
|
||||
Arguments:
|
||||
**kwargs: Keyword arguments to the serialize method, accepts
|
||||
the following keyword args:
|
||||
deterministic: If true, requests deterministic serialization of the
|
||||
protobuf, with predictable ordering of map keys.
|
||||
|
||||
Returns:
|
||||
A binary string representation of the message if all of the required
|
||||
fields in the message are set (i.e. the message is initialized).
|
||||
@ -196,12 +202,18 @@ class Message(object):
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def SerializePartialToString(self):
|
||||
def SerializePartialToString(self, **kwargs):
|
||||
"""Serializes the protocol message to a binary string.
|
||||
|
||||
This method is similar to SerializeToString but doesn't check if the
|
||||
message is initialized.
|
||||
|
||||
Arguments:
|
||||
**kwargs: Keyword arguments to the serialize method, accepts
|
||||
the following keyword args:
|
||||
deterministic: If true, requests deterministic serialization of the
|
||||
protobuf, with predictable ordering of map keys.
|
||||
|
||||
Returns:
|
||||
A string representation of the partial message.
|
||||
"""
|
||||
|
@ -66,7 +66,7 @@ class MessageFactory(object):
|
||||
Returns:
|
||||
A class describing the passed in descriptor.
|
||||
"""
|
||||
if descriptor.full_name not in self._classes:
|
||||
if descriptor not in self._classes:
|
||||
descriptor_name = descriptor.name
|
||||
if str is bytes: # PY2
|
||||
descriptor_name = descriptor.name.encode('ascii', 'ignore')
|
||||
@ -75,16 +75,16 @@ class MessageFactory(object):
|
||||
(message.Message,),
|
||||
{'DESCRIPTOR': descriptor, '__module__': None})
|
||||
# If module not set, it wrongly points to the reflection.py module.
|
||||
self._classes[descriptor.full_name] = result_class
|
||||
self._classes[descriptor] = result_class
|
||||
for field in descriptor.fields:
|
||||
if field.message_type:
|
||||
self.GetPrototype(field.message_type)
|
||||
for extension in result_class.DESCRIPTOR.extensions:
|
||||
if extension.containing_type.full_name not in self._classes:
|
||||
if extension.containing_type not in self._classes:
|
||||
self.GetPrototype(extension.containing_type)
|
||||
extended_class = self._classes[extension.containing_type.full_name]
|
||||
extended_class = self._classes[extension.containing_type]
|
||||
extended_class.RegisterExtension(extension)
|
||||
return self._classes[descriptor.full_name]
|
||||
return self._classes[descriptor]
|
||||
|
||||
def GetMessages(self, files):
|
||||
"""Gets all the messages from a specified file.
|
||||
@ -116,9 +116,9 @@ class MessageFactory(object):
|
||||
# an error if they were different.
|
||||
|
||||
for extension in file_desc.extensions_by_name.values():
|
||||
if extension.containing_type.full_name not in self._classes:
|
||||
if extension.containing_type not in self._classes:
|
||||
self.GetPrototype(extension.containing_type)
|
||||
extended_class = self._classes[extension.containing_type.full_name]
|
||||
extended_class = self._classes[extension.containing_type]
|
||||
extended_class.RegisterExtension(extension)
|
||||
return result
|
||||
|
||||
|
@ -709,6 +709,10 @@ static PyObject* GetJsonName(PyBaseDescriptor* self, void *closure) {
|
||||
return PyString_FromCppString(_GetDescriptor(self)->json_name());
|
||||
}
|
||||
|
||||
static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
|
||||
return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
|
||||
}
|
||||
|
||||
static PyObject* GetType(PyBaseDescriptor *self, void *closure) {
|
||||
return PyInt_FromLong(_GetDescriptor(self)->type());
|
||||
}
|
||||
@ -899,6 +903,7 @@ static PyGetSetDef Getters[] = {
|
||||
{ "name", (getter)GetName, NULL, "Unqualified name"},
|
||||
{ "camelcase_name", (getter)GetCamelcaseName, NULL, "Camelcase name"},
|
||||
{ "json_name", (getter)GetJsonName, NULL, "Json name"},
|
||||
{ "file", (getter)GetFile, NULL, "File Descriptor"},
|
||||
{ "type", (getter)GetType, NULL, "C++ Type"},
|
||||
{ "cpp_type", (getter)GetCppType, NULL, "C++ Type"},
|
||||
{ "label", (getter)GetLabel, NULL, "Label"},
|
||||
@ -1570,6 +1575,10 @@ static PyObject* GetFullName(PyBaseDescriptor* self, void *closure) {
|
||||
return PyString_FromCppString(_GetDescriptor(self)->full_name());
|
||||
}
|
||||
|
||||
static PyObject* GetFile(PyBaseDescriptor *self, void *closure) {
|
||||
return PyFileDescriptor_FromDescriptor(_GetDescriptor(self)->file());
|
||||
}
|
||||
|
||||
static PyObject* GetIndex(PyBaseDescriptor *self, void *closure) {
|
||||
return PyInt_FromLong(_GetDescriptor(self)->index());
|
||||
}
|
||||
@ -1611,6 +1620,7 @@ static PyObject* CopyToProto(PyBaseDescriptor *self, PyObject *target) {
|
||||
static PyGetSetDef Getters[] = {
|
||||
{ "name", (getter)GetName, NULL, "Name", NULL},
|
||||
{ "full_name", (getter)GetFullName, NULL, "Full name", NULL},
|
||||
{ "file", (getter)GetFile, NULL, "File descriptor"},
|
||||
{ "index", (getter)GetIndex, NULL, "Index", NULL},
|
||||
|
||||
{ "methods", (getter)GetMethods, NULL, "Methods", NULL},
|
||||
|
@ -712,8 +712,30 @@ int MapReflectionFriend::MessageMapSetItem(PyObject* _self, PyObject* key,
|
||||
}
|
||||
|
||||
// Delete key from map.
|
||||
if (reflection->DeleteMapValue(message, self->parent_field_descriptor,
|
||||
if (reflection->ContainsMapKey(*message, self->parent_field_descriptor,
|
||||
map_key)) {
|
||||
// Delete key from CMessage dict.
|
||||
MapValueRef value;
|
||||
reflection->InsertOrLookupMapValue(message, self->parent_field_descriptor,
|
||||
map_key, &value);
|
||||
ScopedPyObjectPtr key(PyLong_FromVoidPtr(value.MutableMessageValue()));
|
||||
|
||||
// PyDict_DelItem will have key error if the key is not in the map. We do
|
||||
// not want to call PyErr_Clear() which may clear other errors. Thus
|
||||
// PyDict_Contains() check is called before delete.
|
||||
int contains = PyDict_Contains(self->message_dict, key.get());
|
||||
if (contains < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (contains) {
|
||||
if (PyDict_DelItem(self->message_dict, key.get()) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete key from map.
|
||||
reflection->DeleteMapValue(message, self->parent_field_descriptor,
|
||||
map_key);
|
||||
return 0;
|
||||
} else {
|
||||
PyErr_Format(PyExc_KeyError, "Key not present in map");
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <google/protobuf/stubs/common.h>
|
||||
#include <google/protobuf/stubs/logging.h>
|
||||
#include <google/protobuf/io/coded_stream.h>
|
||||
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
|
||||
#include <google/protobuf/util/message_differencer.h>
|
||||
#include <google/protobuf/descriptor.h>
|
||||
#include <google/protobuf/message.h>
|
||||
@ -1808,8 +1809,25 @@ static string GetMessageName(CMessage* self) {
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject* SerializeToString(CMessage* self, PyObject* args) {
|
||||
if (!self->message->IsInitialized()) {
|
||||
static PyObject* InternalSerializeToString(
|
||||
CMessage* self, PyObject* args, PyObject* kwargs,
|
||||
bool require_initialized) {
|
||||
// Parse the "deterministic" kwarg; defaults to False.
|
||||
static char* kwlist[] = { "deterministic", 0 };
|
||||
PyObject* deterministic_obj = Py_None;
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist,
|
||||
&deterministic_obj)) {
|
||||
return NULL;
|
||||
}
|
||||
// Preemptively convert to a bool first, so we don't need to back out of
|
||||
// allocating memory if this raises an exception.
|
||||
// NOTE: This is unused later if deterministic == Py_None, but that's fine.
|
||||
int deterministic = PyObject_IsTrue(deterministic_obj);
|
||||
if (deterministic < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (require_initialized && !self->message->IsInitialized()) {
|
||||
ScopedPyObjectPtr errors(FindInitializationErrors(self));
|
||||
if (errors == NULL) {
|
||||
return NULL;
|
||||
@ -1847,24 +1865,36 @@ static PyObject* SerializeToString(CMessage* self, PyObject* args) {
|
||||
GetMessageName(self).c_str(), PyString_AsString(joined.get()));
|
||||
return NULL;
|
||||
}
|
||||
int size = self->message->ByteSize();
|
||||
if (size <= 0) {
|
||||
|
||||
// Ok, arguments parsed and errors checked, now encode to a string
|
||||
const size_t size = self->message->ByteSizeLong();
|
||||
if (size == 0) {
|
||||
return PyBytes_FromString("");
|
||||
}
|
||||
PyObject* result = PyBytes_FromStringAndSize(NULL, size);
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
char* buffer = PyBytes_AS_STRING(result);
|
||||
self->message->SerializeWithCachedSizesToArray(
|
||||
reinterpret_cast<uint8*>(buffer));
|
||||
io::ArrayOutputStream out(PyBytes_AS_STRING(result), size);
|
||||
io::CodedOutputStream coded_out(&out);
|
||||
if (deterministic_obj != Py_None) {
|
||||
coded_out.SetSerializationDeterministic(deterministic);
|
||||
}
|
||||
self->message->SerializeWithCachedSizes(&coded_out);
|
||||
GOOGLE_CHECK(!coded_out.HadError());
|
||||
return result;
|
||||
}
|
||||
|
||||
static PyObject* SerializePartialToString(CMessage* self) {
|
||||
string contents;
|
||||
self->message->SerializePartialToString(&contents);
|
||||
return PyBytes_FromStringAndSize(contents.c_str(), contents.size());
|
||||
static PyObject* SerializeToString(
|
||||
CMessage* self, PyObject* args, PyObject* kwargs) {
|
||||
return InternalSerializeToString(self, args, kwargs,
|
||||
/*require_initialized=*/true);
|
||||
}
|
||||
|
||||
static PyObject* SerializePartialToString(
|
||||
CMessage* self, PyObject* args, PyObject* kwargs) {
|
||||
return InternalSerializeToString(self, args, kwargs,
|
||||
/*require_initialized=*/false);
|
||||
}
|
||||
|
||||
// Formats proto fields for ascii dumps using python formatting functions where
|
||||
@ -2535,7 +2565,10 @@ PyObject* Reduce(CMessage* self) {
|
||||
if (state == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr serialized(SerializePartialToString(self));
|
||||
string contents;
|
||||
self->message->SerializePartialToString(&contents);
|
||||
ScopedPyObjectPtr serialized(
|
||||
PyBytes_FromStringAndSize(contents.c_str(), contents.size()));
|
||||
if (serialized == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -2656,9 +2689,10 @@ static PyMethodDef Methods[] = {
|
||||
{ "RegisterExtension", (PyCFunction)RegisterExtension, METH_O | METH_CLASS,
|
||||
"Registers an extension with the current message." },
|
||||
{ "SerializePartialToString", (PyCFunction)SerializePartialToString,
|
||||
METH_NOARGS,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
"Serializes the message to a string, even if it isn't initialized." },
|
||||
{ "SerializeToString", (PyCFunction)SerializeToString, METH_NOARGS,
|
||||
{ "SerializeToString", (PyCFunction)SerializeToString,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
"Serializes the message to a string, only for initialized messages." },
|
||||
{ "SetInParent", (PyCFunction)SetInParent, METH_NOARGS,
|
||||
"Sets the has bit of the given field in its parent message." },
|
||||
|
@ -133,11 +133,7 @@ int RegisterMessageClass(PyMessageFactory* self,
|
||||
CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self,
|
||||
const Descriptor* descriptor) {
|
||||
// This is the same implementation as MessageFactory.GetPrototype().
|
||||
ScopedPyObjectPtr py_descriptor(
|
||||
PyMessageDescriptor_FromDescriptor(descriptor));
|
||||
if (py_descriptor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Do not create a MessageClass that already exists.
|
||||
hash_map<const Descriptor*, CMessageClass*>::iterator it =
|
||||
self->classes_by_descriptor->find(descriptor);
|
||||
@ -145,6 +141,11 @@ CMessageClass* GetOrCreateMessageClass(PyMessageFactory* self,
|
||||
Py_INCREF(it->second);
|
||||
return it->second;
|
||||
}
|
||||
ScopedPyObjectPtr py_descriptor(
|
||||
PyMessageDescriptor_FromDescriptor(descriptor));
|
||||
if (py_descriptor == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
// Create a new message class.
|
||||
ScopedPyObjectPtr args(Py_BuildValue(
|
||||
"s(){sOsOsO}", descriptor->name().c_str(),
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include <google/protobuf/pyext/descriptor.h>
|
||||
#include <google/protobuf/pyext/descriptor_pool.h>
|
||||
#include <google/protobuf/pyext/message.h>
|
||||
#include <google/protobuf/pyext/message_factory.h>
|
||||
#include <google/protobuf/pyext/scoped_pyobject_ptr.h>
|
||||
#include <google/protobuf/reflection.h>
|
||||
|
||||
@ -137,9 +138,12 @@ static PyObject* AddToAttached(RepeatedCompositeContainer* self,
|
||||
if (cmessage::AssureWritable(self->parent) == -1)
|
||||
return NULL;
|
||||
Message* message = self->message;
|
||||
|
||||
Message* sub_message =
|
||||
message->GetReflection()->AddMessage(message,
|
||||
self->parent_field_descriptor);
|
||||
message->GetReflection()->AddMessage(
|
||||
message,
|
||||
self->parent_field_descriptor,
|
||||
self->child_message_class->py_message_factory->message_factory);
|
||||
CMessage* cmsg = cmessage::NewEmptyMessage(self->child_message_class);
|
||||
if (cmsg == NULL)
|
||||
return NULL;
|
||||
@ -335,6 +339,18 @@ static PyObject* RichCompare(RepeatedCompositeContainer* self,
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject* ToStr(RepeatedCompositeContainer* self) {
|
||||
ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
|
||||
if (full_slice == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return PyObject_Repr(list.get());
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// sort()
|
||||
|
||||
@ -607,7 +623,7 @@ PyTypeObject RepeatedCompositeContainer_Type = {
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
0, // tp_repr
|
||||
(reprfunc)repeated_composite_container::ToStr, // tp_repr
|
||||
0, // tp_as_number
|
||||
&repeated_composite_container::SqMethods, // tp_as_sequence
|
||||
&repeated_composite_container::MpMethods, // tp_as_mapping
|
||||
|
@ -656,6 +656,18 @@ static PyObject* Pop(RepeatedScalarContainer* self,
|
||||
return item;
|
||||
}
|
||||
|
||||
static PyObject* ToStr(RepeatedScalarContainer* self) {
|
||||
ScopedPyObjectPtr full_slice(PySlice_New(NULL, NULL, NULL));
|
||||
if (full_slice == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ScopedPyObjectPtr list(Subscript(self, full_slice.get()));
|
||||
if (list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return PyObject_Repr(list.get());
|
||||
}
|
||||
|
||||
// The private constructor of RepeatedScalarContainer objects.
|
||||
PyObject *NewContainer(
|
||||
CMessage* parent, const FieldDescriptor* parent_field_descriptor) {
|
||||
@ -778,7 +790,7 @@ PyTypeObject RepeatedScalarContainer_Type = {
|
||||
0, // tp_getattr
|
||||
0, // tp_setattr
|
||||
0, // tp_compare
|
||||
0, // tp_repr
|
||||
(reprfunc)repeated_scalar_container::ToStr, // tp_repr
|
||||
0, // tp_as_number
|
||||
&repeated_scalar_container::SqMethods, // tp_as_sequence
|
||||
&repeated_scalar_container::MpMethods, // tp_as_mapping
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user