diff --git a/BUILD b/BUILD index 5d4541dc77..afad437c10 100644 --- a/BUILD +++ b/BUILD @@ -739,10 +739,9 @@ py_library( name = "python_srcs", srcs = glob( [ - "python/google/**/*.py", + "python/google/protobuf/**/*.py", ], exclude = [ - "python/google/protobuf/**/__init__.py", "python/google/protobuf/internal/*_test.py", "python/google/protobuf/internal/test_util.py", ], @@ -843,7 +842,6 @@ py_proto_library( }), default_runtime = "", protoc = ":protoc", - py_extra_srcs = glob(["python/**/__init__.py"]), py_libs = [ ":python_srcs", "@six//:six", diff --git a/benchmarks/README.md b/benchmarks/README.md index 436c148a34..76788175c6 100644 --- a/benchmarks/README.md +++ b/benchmarks/README.md @@ -135,7 +135,7 @@ $ make go ### PHP -We have two version of php protobuf implemention: pure php, php with c extension. To run these version benchmark, you need to: +We have two version of php protobuf implementation: pure php, php with c extension. To run these version benchmark, you need to: #### Pure PHP ``` $ make php diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index 007cc80669..f8fc0e9813 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -53,7 +53,6 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\generated_message_tab 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\implicit_weak_message.h" include\google\protobuf\implicit_weak_message.h -copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\inlined_string_field.h" include\google\protobuf\inlined_string_field.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\coded_stream.h" include\google\protobuf\io\coded_stream.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\gzip_stream.h" include\google\protobuf\io\gzip_stream.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\io\io_win32.h" include\google\protobuf\io\io_win32.h diff --git a/cmake/libprotobuf-lite.cmake b/cmake/libprotobuf-lite.cmake index bbba6071f7..75d8d71ce9 100644 --- a/cmake/libprotobuf-lite.cmake +++ b/cmake/libprotobuf-lite.cmake @@ -1,6 +1,7 @@ set(libprotobuf_lite_files ${protobuf_source_dir}/src/google/protobuf/any_lite.cc ${protobuf_source_dir}/src/google/protobuf/arena.cc + ${protobuf_source_dir}/src/google/protobuf/arenastring.cc ${protobuf_source_dir}/src/google/protobuf/extension_set.cc ${protobuf_source_dir}/src/google/protobuf/generated_enum_util.cc ${protobuf_source_dir}/src/google/protobuf/generated_message_table_driven_lite.cc diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index 0c12596c23..d7d077067a 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -2,6 +2,7 @@ set(libprotobuf_files ${protobuf_source_dir}/src/google/protobuf/any.cc ${protobuf_source_dir}/src/google/protobuf/any.pb.cc ${protobuf_source_dir}/src/google/protobuf/api.pb.cc + ${protobuf_source_dir}/src/google/protobuf/arenastring.cc ${protobuf_source_dir}/src/google/protobuf/compiler/importer.cc ${protobuf_source_dir}/src/google/protobuf/compiler/parser.cc ${protobuf_source_dir}/src/google/protobuf/descriptor.cc diff --git a/cmake/protobuf-config.cmake.in b/cmake/protobuf-config.cmake.in index 11b85d3c07..fac5efe440 100644 --- a/cmake/protobuf-config.cmake.in +++ b/cmake/protobuf-config.cmake.in @@ -99,13 +99,17 @@ function(protobuf_generate) foreach(_proto ${protobuf_generate_PROTOS}) get_filename_component(_abs_file ${_proto} ABSOLUTE) get_filename_component(_abs_dir ${_abs_file} DIRECTORY) - get_filename_component(_basename ${_proto} NAME_WLE) + + get_filename_component(_file_full_name ${_proto} NAME) + string(FIND "${_file_full_name}" "." _file_last_ext_pos REVERSE) + string(SUBSTRING "${_file_full_name}" 0 ${_file_last_ext_pos} _basename) set(_suitable_include_found FALSE) foreach(DIR ${_protobuf_include_path}) if(NOT DIR STREQUAL "-I") file(RELATIVE_PATH _rel_dir ${DIR} ${_abs_dir}) - if(NOT "${_rel_dir}" MATCHES "^\.\.[/\\].*") + string(FIND "${_rel_dir}" "../" _is_in_parent_folder) + if (NOT ${_is_in_parent_folder} EQUAL 0) set(_suitable_include_found TRUE) break() endif() diff --git a/conformance/failure_list_js.txt b/conformance/failure_list_js.txt index ef9131a78e..e69de29bb2 100644 --- a/conformance/failure_list_js.txt +++ b/conformance/failure_list_js.txt @@ -1,115 +0,0 @@ - -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto2.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.PackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.UnpackedOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.DefaultOutput.ProtobufOutput -Recommended.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.PackedOutput.ProtobufOutput -Required.Proto3.ProtobufInput.RepeatedScalarMessageMerge.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataMap.STRING.MESSAGE.MergeValue.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.BOOL.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.DOUBLE.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.ENUM.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.FIXED64.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.FLOAT.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.INT32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.INT64.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.SFIXED64.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.SINT32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.SINT64.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.UINT32.PackedInput.ProtobufOutput -Required.Proto2.ProtobufInput.ValidDataRepeated.UINT64.PackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.BOOL.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.DOUBLE.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.ENUM.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FIXED64.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.FLOAT.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.INT32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.INT64.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.SFIXED64.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.SINT32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.SINT64.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.UINT32.UnpackedInput.ProtobufOutput -Required.Proto3.ProtobufInput.ValidDataRepeated.UINT64.UnpackedInput.ProtobufOutput diff --git a/conformance/text_format_conformance_suite.cc b/conformance/text_format_conformance_suite.cc index 6574b10c50..78462c4763 100644 --- a/conformance/text_format_conformance_suite.cc +++ b/conformance/text_format_conformance_suite.cc @@ -258,6 +258,85 @@ void TextFormatConformanceTestSuite::RunSuiteImpl() { RunValidTextFormatTest("FloatFieldLargerThanUint64", REQUIRED, "optional_float: 18446744073709551616"); + // String literals x {Strings, Bytes} + for (const auto& field_type : + std::vector{"String", "Bytes"}) { + const std::string field_name = + field_type == "String" ? "optional_string" : "optional_bytes"; + RunValidTextFormatTest( + StrCat("StringLiteralConcat", field_type), REQUIRED, + StrCat(field_name, ": 'first' \"second\"\n'third'")); + RunValidTextFormatTest( + StrCat("StringLiteralBasicEscapes", field_type), REQUIRED, + StrCat(field_name, ": '\\a\\b\\f\\n\\r\\t\\v\\?\\\\\\'\\\"'")); + RunValidTextFormatTest( + StrCat("StringLiteralOctalEscapes", field_type), REQUIRED, + StrCat(field_name, ": '\\341\\210\\264'")); + RunValidTextFormatTest(StrCat("StringLiteralHexEscapes", field_type), + REQUIRED, + StrCat(field_name, ": '\\xe1\\x88\\xb4'")); + RunValidTextFormatTest( + StrCat("StringLiteralShortUnicodeEscape", field_type), + RECOMMENDED, StrCat(field_name, ": '\\u1234'")); + RunValidTextFormatTest( + StrCat("StringLiteralLongUnicodeEscapes", field_type), + RECOMMENDED, StrCat(field_name, ": '\\U00001234\\U00010437'")); + // String literals don't include line feeds. + ExpectParseFailure(StrCat("StringLiteralIncludesLF", field_type), + REQUIRED, + StrCat(field_name, ": 'first line\nsecond line'")); + // Unicode escapes don't include code points that lie beyond the planes + // (> 0x10ffff). + ExpectParseFailure( + StrCat("StringLiteralLongUnicodeEscapeTooLarge", field_type), + REQUIRED, StrCat(field_name, ": '\\U00110000'")); + // Unicode escapes don't include surrogates. + ExpectParseFailure( + StrCat("StringLiteralShortUnicodeEscapeSurrogatePair", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\ud801\\udc37'")); + ExpectParseFailure( + StrCat("StringLiteralShortUnicodeEscapeSurrogateFirstOnly", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\ud800'")); + ExpectParseFailure( + StrCat("StringLiteralShortUnicodeEscapeSurrogateSecondOnly", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\udc00'")); + ExpectParseFailure( + StrCat("StringLiteralLongUnicodeEscapeSurrogateFirstOnly", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\U0000d800'")); + ExpectParseFailure( + StrCat("StringLiteralLongUnicodeEscapeSurrogateSecondOnly", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\U0000dc00'")); + ExpectParseFailure( + StrCat("StringLiteralLongUnicodeEscapeSurrogatePair", field_type), + RECOMMENDED, StrCat(field_name, ": '\\U0000d801\\U00000dc37'")); + ExpectParseFailure( + StrCat("StringLiteralUnicodeEscapeSurrogatePairLongShort", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\U0000d801\\udc37'")); + ExpectParseFailure( + StrCat("StringLiteralUnicodeEscapeSurrogatePairShortLong", + field_type), + RECOMMENDED, StrCat(field_name, ": '\\ud801\\U0000dc37'")); + + // The following method depend on the type of field, as strings have extra + // validation. + const auto test_method = + field_type == "String" + ? &TextFormatConformanceTestSuite::ExpectParseFailure + : &TextFormatConformanceTestSuite::RunValidTextFormatTest; + + // String fields reject invalid UTF-8 byte sequences; bytes fields don't. + (this->*test_method)(StrCat(field_type, "FieldBadUTF8Octal"), + REQUIRED, StrCat(field_name, ": '\\300'")); + (this->*test_method)(StrCat(field_type, "FieldBadUTF8Hex"), REQUIRED, + StrCat(field_name, ": '\\xc0'")); + } + // Group fields RunValidTextFormatTestProto2("GroupFieldNoColon", REQUIRED, "Data { group_int32: 1 }"); diff --git a/conformance/text_format_failure_list_cpp.txt b/conformance/text_format_failure_list_cpp.txt new file mode 100644 index 0000000000..a25f04faf2 --- /dev/null +++ b/conformance/text_format_failure_list_cpp.txt @@ -0,0 +1,20 @@ +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex +Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeBytes +Required.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeTooLargeString diff --git a/conformance/text_format_failure_list_java.txt b/conformance/text_format_failure_list_java.txt index 81433b441a..8f74bdfb7e 100644 --- a/conformance/text_format_failure_list_java.txt +++ b/conformance/text_format_failure_list_java.txt @@ -4,3 +4,18 @@ Recommended.Proto3.ProtobufInput.RepeatedUnknownFields_Drop.TextFormatOutput Recommended.Proto3.ProtobufInput.ScalarUnknownFields_Drop.TextFormatOutput Required.Proto3.TextFormatInput.AnyField.ProtobufOutput Required.Proto3.TextFormatInput.AnyField.TextFormatOutput + +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Required.Proto3.TextFormatInput.StringFieldBadUTF8Hex +Required.Proto3.TextFormatInput.StringFieldBadUTF8Octal +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/conformance/text_format_failure_list_python.txt b/conformance/text_format_failure_list_python.txt index b2db95e7de..6bf7c1aa63 100644 --- a/conformance/text_format_failure_list_python.txt +++ b/conformance/text_format_failure_list_python.txt @@ -3,3 +3,32 @@ # TODO: These should be fixed. Required.Proto3.TextFormatInput.FloatFieldMaxValue.ProtobufOutput Required.Proto3.TextFormatInput.FloatFieldMaxValue.TextFormatOutput + +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/conformance/text_format_failure_list_python_cpp.txt b/conformance/text_format_failure_list_python_cpp.txt new file mode 100644 index 0000000000..91fc2ea3cd --- /dev/null +++ b/conformance/text_format_failure_list_python_cpp.txt @@ -0,0 +1,28 @@ +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralLongUnicodeEscapesString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeBytes.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.ProtobufOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeString.TextFormatOutput +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateFirstOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogatePairString +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyBytes +Recommended.Proto3.TextFormatInput.StringLiteralShortUnicodeEscapeSurrogateSecondOnlyString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairLongShortString +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongBytes +Recommended.Proto3.TextFormatInput.StringLiteralUnicodeEscapeSurrogatePairShortLongString +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesBytes.TextFormatOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.ProtobufOutput +Required.Proto3.TextFormatInput.StringLiteralBasicEscapesString.TextFormatOutput diff --git a/docs/options.md b/docs/options.md index fd1e813797..f64b9ea8e1 100644 --- a/docs/options.md +++ b/docs/options.md @@ -248,3 +248,7 @@ with info about your project (name and website) so we can add an entry for you. 1. Wire wire_package * Website: https://square.github.io/wire/ * Extensions: 1087 + +1. Confluent Schema Registry + * Website: https://github.com/confluentinc/schema-registry + * Extensions: 1088 diff --git a/docs/third_party.md b/docs/third_party.md index b9c66c02f1..7799e308a7 100644 --- a/docs/third_party.md +++ b/docs/third_party.md @@ -84,6 +84,7 @@ These are projects we know about implementing Protocol Buffers for other program * PHP: https://github.com/chobie/php-protocolbuffers * PHP: http://drslump.github.com/Protobuf-PHP * Prolog: http://www.swi-prolog.org/pldoc/package/protobufs.html +* Purescript: https://github.com/xc-jp/purescript-protobuf * Python: https://github.com/google/protobuf (Google-official implementation) * Python: https://github.com/eigenein/protobuf * Python: https://github.com/danielgtaylor/python-betterproto diff --git a/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java b/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java index 3220f64072..e792d7d981 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractProtobufList.java @@ -142,7 +142,12 @@ abstract class AbstractProtobufList extends AbstractList implements Protob @Override public boolean remove(Object o) { ensureIsMutable(); - return super.remove(o); + int index = indexOf(o); + if (index == -1) { + return false; + } + remove(index); + return true; } @Override diff --git a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java index f023baa9a0..451fce1e84 100644 --- a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java @@ -267,20 +267,6 @@ final class BooleanArrayList extends AbstractProtobufList return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Boolean remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java index 12824abe66..4085653437 100644 --- a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java @@ -267,20 +267,6 @@ final class DoubleArrayList extends AbstractProtobufList return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Double remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java index 9589816f8e..e6feba8a35 100644 --- a/java/core/src/main/java/com/google/protobuf/FloatArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/FloatArrayList.java @@ -266,20 +266,6 @@ final class FloatArrayList extends AbstractProtobufList return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Float remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/IntArrayList.java b/java/core/src/main/java/com/google/protobuf/IntArrayList.java index e9c3b1aee0..9daeebed99 100644 --- a/java/core/src/main/java/com/google/protobuf/IntArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/IntArrayList.java @@ -266,20 +266,6 @@ final class IntArrayList extends AbstractProtobufList return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Integer remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/Internal.java b/java/core/src/main/java/com/google/protobuf/Internal.java index 0826351bcb..90643b8abb 100644 --- a/java/core/src/main/java/com/google/protobuf/Internal.java +++ b/java/core/src/main/java/com/google/protobuf/Internal.java @@ -30,7 +30,6 @@ package com.google.protobuf; -import java.io.IOException; import java.lang.reflect.Method; import java.nio.ByteBuffer; import java.nio.charset.Charset; diff --git a/java/core/src/main/java/com/google/protobuf/LongArrayList.java b/java/core/src/main/java/com/google/protobuf/LongArrayList.java index 04f44756c4..bda43a41bb 100644 --- a/java/core/src/main/java/com/google/protobuf/LongArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/LongArrayList.java @@ -266,20 +266,6 @@ final class LongArrayList extends AbstractProtobufList return true; } - @Override - public boolean remove(Object o) { - ensureIsMutable(); - for (int i = 0; i < size; i++) { - if (o.equals(array[i])) { - System.arraycopy(array, i + 1, array, i, size - i - 1); - size--; - modCount++; - return true; - } - } - return false; - } - @Override public Long remove(int index) { ensureIsMutable(); diff --git a/java/core/src/main/java/com/google/protobuf/MessageSchema.java b/java/core/src/main/java/com/google/protobuf/MessageSchema.java index 28879d7785..33c8e914b2 100644 --- a/java/core/src/main/java/com/google/protobuf/MessageSchema.java +++ b/java/core/src/main/java/com/google/protobuf/MessageSchema.java @@ -2572,7 +2572,7 @@ final class MessageSchema implements Schema { int presenceMaskAndOffset = 0; int presenceMask = 0; - if (!proto3 && fieldType <= 17) { + if (fieldType <= 17) { presenceMaskAndOffset = buffer[pos + 2]; final int presenceFieldOffset = presenceMaskAndOffset & OFFSET_MASK; if (presenceFieldOffset != currentPresenceFieldOffset) { diff --git a/java/core/src/main/java/com/google/protobuf/Protobuf.java b/java/core/src/main/java/com/google/protobuf/Protobuf.java index adaa7fa8f2..0affac5f0a 100644 --- a/java/core/src/main/java/com/google/protobuf/Protobuf.java +++ b/java/core/src/main/java/com/google/protobuf/Protobuf.java @@ -76,11 +76,8 @@ final class Protobuf { schemaFor(message).makeImmutable(message); } - /** - * Checks if all required fields are set. TODO(xiaofeng): Make this package private when the tests - * are moved to protobuf package. - */ - public boolean isInitialized(T message) { + /** Checks if all required fields are set. */ + boolean isInitialized(T message) { return schemaFor(message).isInitialized(message); } diff --git a/java/core/src/main/java/com/google/protobuf/RopeByteString.java b/java/core/src/main/java/com/google/protobuf/RopeByteString.java index 54d4180595..cc6e0445b0 100644 --- a/java/core/src/main/java/com/google/protobuf/RopeByteString.java +++ b/java/core/src/main/java/com/google/protobuf/RopeByteString.java @@ -845,7 +845,10 @@ final class RopeByteString extends ByteString { throw new IndexOutOfBoundsException(); } int bytesRead = readSkipInternal(b, offset, length); - if (bytesRead == 0) { + if (bytesRead == 0 && (length > 0 || availableInternal() == 0)) { + // Modeling ByteArrayInputStream.read(byte[], int, int) behavior noted above: + // It's ok to read 0 bytes on purpose (length == 0) from a stream that isn't at EOF. + // It's not ok to try to read bytes (even 0 bytes) from a stream that is at EOF. return -1; } else { return bytesRead; @@ -905,8 +908,7 @@ final class RopeByteString extends ByteString { @Override public int available() throws IOException { - int bytesRead = currentPieceOffsetInRope + currentPieceIndex; - return RopeByteString.this.size() - bytesRead; + return availableInternal(); } @Override @@ -955,5 +957,11 @@ final class RopeByteString extends ByteString { } } } + + /** Computes the number of bytes still available to read. */ + private int availableInternal() { + int bytesRead = currentPieceOffsetInRope + currentPieceIndex; + return RopeByteString.this.size() - bytesRead; + } } } diff --git a/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java index 9f64b6baba..4177a47e67 100644 --- a/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java +++ b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java @@ -514,6 +514,20 @@ public class LiteralByteStringTest extends TestCase { assertEquals(classUnderTest + " InputStream must now be exhausted", -1, input.read()); } + public void testNewInput_readZeroBytes() throws IOException { + InputStream input = stringUnderTest.newInput(); + assertEquals( + classUnderTest + " InputStream.read() returns 0 when told to read 0 bytes and not at EOF", + 0, + input.read(new byte[0])); + + input.skip(input.available()); + assertEquals( + classUnderTest + " InputStream.read() returns -1 when told to read 0 bytes at EOF", + -1, + input.read(new byte[0])); + } + public void testNewInput_skip() throws IOException { InputStream input = stringUnderTest.newInput(); int stringSize = stringUnderTest.size(); diff --git a/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java b/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java index 57e933f3a4..a17dda5c1f 100644 --- a/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java +++ b/java/lite/src/test/java/com/google/protobuf/Proto2MessageLiteInfoFactory.java @@ -174,8 +174,9 @@ public final class Proto2MessageLiteInfoFactory implements MessageInfoFactory { "fieldRequiredSint6487_", "fieldRequiredGroup88_", }; - // To update this after a proto change, run protoc on proto2_message_lite.proto and copy over - // the content of the generated buildMessageInfo() method here. + // To update this after a proto change, run blaze build on proto2_message_lite.proto and copy + // over the String info from the proto2_message_lite_proto-lite-src.jar file in the + // blaze-genfiles directory. java.lang.String info = "\u0001U\u0001\u0002\u0001XU\u0000 \u0015\u0001\u1000\u0000\u0002\u1001\u0001\u0003" + "\u1002\u0002\u0004\u1003\u0003\u0005\u1004\u0004\u0006\u1005\u0005\u0007\u1006\u0006\b\u1007\u0007" diff --git a/js/binary/constants.js b/js/binary/constants.js index f8b13a8b9e..d2e62e5b0f 100644 --- a/js/binary/constants.js +++ b/js/binary/constants.js @@ -31,6 +31,7 @@ /** * @fileoverview This file contains constants and typedefs used by * jspb.BinaryReader and BinaryWriter. + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * * @author aappleby@google.com (Austin Appleby) */ diff --git a/js/binary/decoder.js b/js/binary/decoder.js index 257c283f09..fb40ec99e3 100644 --- a/js/binary/decoder.js +++ b/js/binary/decoder.js @@ -40,6 +40,7 @@ * intact, you _must_ read them using one of the Hash64 methods, which return * an 8-character string. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author aappleby@google.com (Austin Appleby) */ diff --git a/js/binary/reader.js b/js/binary/reader.js index 2af1a4ac39..6fdbd6f4dc 100644 --- a/js/binary/reader.js +++ b/js/binary/reader.js @@ -41,6 +41,7 @@ * using the typed jspb code generator, but if you bypass that you'll need * to keep things in sync by hand. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author aappleby@google.com (Austin Appleby) */ diff --git a/js/binary/utils.js b/js/binary/utils.js index 203eec14f2..6cd15e3644 100644 --- a/js/binary/utils.js +++ b/js/binary/utils.js @@ -32,6 +32,7 @@ * @fileoverview This file contains helper code used by jspb.BinaryReader * and BinaryWriter. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author aappleby@google.com (Austin Appleby) */ diff --git a/js/binary/writer.js b/js/binary/writer.js index ab9a815056..1e2beee3e9 100644 --- a/js/binary/writer.js +++ b/js/binary/writer.js @@ -52,6 +52,7 @@ * Major caveat 3 - This class uses typed arrays and must not be used on older * browsers that do not support them. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author aappleby@google.com (Austin Appleby) */ diff --git a/js/map.js b/js/map.js index 589a2938d5..61f0f3b63f 100644 --- a/js/map.js +++ b/js/map.js @@ -1,3 +1,4 @@ + // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // https://developers.google.com/protocol-buffers/ @@ -28,6 +29,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/** + * @fileoverview + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed + */ goog.provide('jspb.Map'); goog.require('goog.asserts'); diff --git a/js/message.js b/js/message.js index f190894b26..905329fe44 100644 --- a/js/message.js +++ b/js/message.js @@ -31,6 +31,7 @@ /** * @fileoverview Definition of jspb.Message. * + * @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed * @author mwr@google.com (Mark Rawling) */ diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index 4615ed31aa..0fa9bf0e5b 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -41,6 +41,7 @@ #include "arena.h" #include "convert.h" #include "def.h" +#include "message.h" #include "php-upb.h" #include "protobuf.h" @@ -94,6 +95,26 @@ static void RepeatedField_destructor(zend_object* obj) { zend_object_std_dtor(&intern->std); } +/** + * RepeatedField_compare_objects() + * + * Object handler for comparing two repeated field objects. Called whenever PHP + * code does: + * + * $rf1 == $rf2 + */ +static int RepeatedField_compare_objects(zval *rf1, zval *rf2) { + RepeatedField* intern1 = (RepeatedField*)Z_OBJ_P(rf1); + RepeatedField* intern2 = (RepeatedField*)Z_OBJ_P(rf2); + upb_fieldtype_t type = intern1->type; + const upb_msgdef *m = intern1->desc ? intern1->desc->msgdef : NULL; + + if (type != intern2->type) return 1; + if (intern1->desc != intern2->desc) return 1; + + return ArrayEq(intern1->array, intern2->array, type, m) ? 0 : 1; +} + static HashTable *RepeatedField_GetProperties(PROTO_VAL *object) { return NULL; // We do not have a properties table. } @@ -177,6 +198,27 @@ upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f, } } +bool ArrayEq(const upb_array *a1, const upb_array *a2, upb_fieldtype_t type, + const upb_msgdef *m) { + size_t i; + size_t n; + + if ((a1 == NULL) != (a2 == NULL)) return false; + if (a1 == NULL) return true; + + n = upb_array_size(a1); + if (n != upb_array_size(a2)) return false; + + for (i = 0; i < n; i++) { + upb_msgval val1 = upb_array_get(a1, i); + upb_msgval val2 = upb_array_get(a2, i); + if (!ValueEq(val1, val2, type, m)) return false; + } + + return true; +} + + // RepeatedField PHP methods /////////////////////////////////////////////////// /** @@ -594,6 +636,7 @@ void Array_ModuleInit() { h = &RepeatedField_object_handlers; memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); h->dtor_obj = RepeatedField_destructor; + h->compare_objects = RepeatedField_compare_objects; h->get_properties = RepeatedField_GetProperties; h->get_property_ptr_ptr = RepeatedField_GetPropertyPtrPtr; diff --git a/php/ext/google/protobuf/array.h b/php/ext/google/protobuf/array.h index 5cf517c566..921e0bf564 100644 --- a/php/ext/google/protobuf/array.h +++ b/php/ext/google/protobuf/array.h @@ -58,4 +58,9 @@ upb_array *RepeatedField_GetUpbArray(zval *val, const upb_fielddef *f, upb_arena void RepeatedField_GetPhpWrapper(zval *val, upb_array *arr, const upb_fielddef *f, zval *arena); +// Returns true if the given arrays are equal. Both arrays must be of this +// |type| and, if the type is |UPB_TYPE_MESSAGE|, must have the same |m|. +bool ArrayEq(const upb_array *a1, const upb_array *a2, upb_fieldtype_t type, + const upb_msgdef *m); + #endif // PHP_PROTOBUF_ARRAY_H_ diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index f29c18c9bd..426d56a4f9 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -37,6 +37,7 @@ #include "arena.h" #include "convert.h" +#include "message.h" #include "php-upb.h" #include "protobuf.h" @@ -90,6 +91,28 @@ static void MapField_destructor(zend_object* obj) { zend_object_std_dtor(&intern->std); } +/** + * MapField_compare_objects() + * + * Object handler for comparing two repeated field objects. Called whenever PHP + * code does: + * + * $map1 == $map2 + */ +static int MapField_compare_objects(zval *map1, zval *map2) { + MapField* intern1 = (MapField*)Z_OBJ_P(map1); + MapField* intern2 = (MapField*)Z_OBJ_P(map2); + const upb_msgdef *m = intern1->desc ? intern1->desc->msgdef : NULL; + upb_fieldtype_t key_type = intern1->key_type; + upb_fieldtype_t val_type = intern1->val_type; + + if (key_type != intern2->key_type) return 1; + if (val_type != intern2->val_type) return 1; + if (intern1->desc != intern2->desc) return 1; + + return MapEq(intern1->map, intern2->map, key_type, val_type, m) ? 0 : 1; +} + static zval *Map_GetPropertyPtrPtr(PROTO_VAL *object, PROTO_STR *member, int type, void **cache_slot) { return NULL; // We don't offer direct references to our properties. @@ -185,6 +208,27 @@ upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena) } } +bool MapEq(const upb_map *m1, const upb_map *m2, upb_fieldtype_t key_type, + upb_fieldtype_t val_type, const upb_msgdef *m) { + size_t iter = UPB_MAP_BEGIN; + + if ((m1 == NULL) != (m2 == NULL)) return false; + if (m1 == NULL) return true; + if (upb_map_size(m1) != upb_map_size(m2)) return false; + + while (upb_mapiter_next(m1, &iter)) { + upb_msgval key = upb_mapiter_key(m1, iter); + upb_msgval val1 = upb_mapiter_value(m1, iter); + upb_msgval val2; + + if (!upb_map_get(m2, key, &val2)) return false; + if (!ValueEq(val1, val2, val_type, m)) return false; + } + + return true; +} + + // MapField PHP methods //////////////////////////////////////////////////////// /** @@ -578,6 +622,7 @@ void Map_ModuleInit() { h = &MapField_object_handlers; memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); h->dtor_obj = MapField_destructor; + h->compare_objects = MapField_compare_objects; h->get_properties = Map_GetProperties; h->get_property_ptr_ptr = Map_GetPropertyPtrPtr; diff --git a/php/ext/google/protobuf/map.h b/php/ext/google/protobuf/map.h index 9b3c9c144c..6eb0620c2e 100644 --- a/php/ext/google/protobuf/map.h +++ b/php/ext/google/protobuf/map.h @@ -57,4 +57,7 @@ upb_map *MapField_GetUpbMap(zval *val, const upb_fielddef *f, upb_arena *arena); void MapField_GetPhpWrapper(zval *val, upb_map *arr, const upb_fielddef *f, zval *arena); +bool MapEq(const upb_map *m1, const upb_map *m2, upb_fieldtype_t key_type, + upb_fieldtype_t val_type, const upb_msgdef *m); + #endif // PHP_PROTOBUF_MAP_H_ diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 63d2b084aa..b2a03063f5 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -108,6 +108,97 @@ static const upb_fielddef *get_field(Message *msg, PROTO_STR *member) { return f; } +static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m); + +/** + * ValueEq()() + */ +bool ValueEq(upb_msgval val1, upb_msgval val2, upb_fieldtype_t type, + const upb_msgdef *m) { + switch (type) { + case UPB_TYPE_BOOL: + return val1.bool_val == val2.bool_val; + case UPB_TYPE_INT32: + case UPB_TYPE_UINT32: + case UPB_TYPE_ENUM: + return val1.int32_val == val2.int32_val; + case UPB_TYPE_INT64: + case UPB_TYPE_UINT64: + return val1.int64_val == val2.int64_val; + case UPB_TYPE_FLOAT: + return val1.float_val == val2.float_val; + case UPB_TYPE_DOUBLE: + return val1.double_val == val2.double_val; + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + return val1.str_val.size == val2.str_val.size && + memcmp(val1.str_val.data, val2.str_val.data, val1.str_val.size) == 0; + case UPB_TYPE_MESSAGE: + return MessageEq(val1.msg_val, val2.msg_val, m); + default: + return false; + } +} + +/** + * MessageEq() + */ +static bool MessageEq(const upb_msg *m1, const upb_msg *m2, const upb_msgdef *m) { + upb_msg_field_iter i; + + for(upb_msg_field_begin(&i, m); + !upb_msg_field_done(&i); + upb_msg_field_next(&i)) { + const upb_fielddef *f = upb_msg_iter_field(&i); + upb_msgval val1 = upb_msg_get(m1, f); + upb_msgval val2 = upb_msg_get(m2, f); + upb_fieldtype_t type = upb_fielddef_type(f); + const upb_msgdef *sub_m = upb_fielddef_msgsubdef(f); + + if (upb_fielddef_haspresence(f)) { + if (upb_msg_has(m1, f) != upb_msg_has(m2, f)) { + return false; + } + if (!upb_msg_has(m1, f)) continue; + } + + if (upb_fielddef_ismap(f)) { + const upb_fielddef *key_f = upb_msgdef_itof(sub_m, 1); + const upb_fielddef *val_f = upb_msgdef_itof(sub_m, 2); + upb_fieldtype_t key_type = upb_fielddef_type(key_f); + upb_fieldtype_t val_type = upb_fielddef_type(val_f); + const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f); + if (!MapEq(val1.map_val, val2.map_val, key_type, val_type, val_m)) { + return false; + } + } else if (upb_fielddef_isseq(f)) { + if (!ArrayEq(val1.array_val, val2.array_val, type, sub_m)) return false; + } else { + if (!ValueEq(val1, val2, type, sub_m)) return false; + } + } + + return true; +} + +/** + * Message_compare_objects() + * + * Object handler for comparing two message objects. Called whenever PHP code + * does: + * + * $m1 == $m2 + */ +static int Message_compare_objects(zval *m1, zval *m2) { + Message* intern1 = (Message*)Z_OBJ_P(m1); + Message* intern2 = (Message*)Z_OBJ_P(m2); + const upb_msgdef *m = intern1->desc->msgdef; + + if (intern2->desc->msgdef != m) return 1; + + return MessageEq(intern1->msg, intern2->msg, m) ? 0 : 1; +} + /** * Message_has_property() * @@ -935,6 +1026,7 @@ void Message_ModuleInit() { memcpy(h, &std_object_handlers, sizeof(zend_object_handlers)); h->dtor_obj = Message_dtor; + h->compare_objects = Message_compare_objects; h->read_property = Message_read_property; h->write_property = Message_write_property; h->has_property = Message_has_property; diff --git a/php/ext/google/protobuf/message.h b/php/ext/google/protobuf/message.h index 5083976016..0e6fb5a4fc 100644 --- a/php/ext/google/protobuf/message.h +++ b/php/ext/google/protobuf/message.h @@ -56,4 +56,7 @@ bool Message_GetUpbMessage(zval *val, const Descriptor *desc, upb_arena *arena, void Message_GetPhpWrapper(zval *val, const Descriptor *desc, upb_msg *msg, zval *arena); +bool ValueEq(upb_msgval val1, upb_msgval val2, upb_fieldtype_t type, + const upb_msgdef *m); + #endif // PHP_PROTOBUF_MESSAGE_H_ diff --git a/php/ext/google/protobuf/php-upb.c b/php/ext/google/protobuf/php-upb.c index 6ce85f1e6a..d1fc36663d 100644 --- a/php/ext/google/protobuf/php-upb.c +++ b/php/ext/google/protobuf/php-upb.c @@ -407,6 +407,7 @@ static const char *decode_varint64(upb_decstate *d, const char *ptr, } } +UPB_FORCEINLINE static const char *decode_varint32(upb_decstate *d, const char *ptr, const char *limit, uint32_t *val) { uint64_t u64; diff --git a/php/tests/ArrayTest.php b/php/tests/ArrayTest.php index 2cb4b3910d..d167331364 100644 --- a/php/tests/ArrayTest.php +++ b/php/tests/ArrayTest.php @@ -590,4 +590,35 @@ class ArrayTest extends \PHPUnit\Framework\TestCase $end = memory_get_usage(); $this->assertLessThan($start, $end); } + + ######################################################### + # Test equality + ######################################################### + + public function testEquality() + { + $arr = new RepeatedField(GPBType::INT32); + $arr2 = new RepeatedField(GPBType::INT32); + + $this->assertTrue($arr == $arr2); + + $arr[] = 0; + $arr[] = 1; + $arr[] = 2; + + $this->assertFalse($arr == $arr2); + + $arr2[] = 0; + $arr2[] = 1; + $arr2[] = 2; + + $this->assertTrue($arr == $arr2); + + // Arrays of different types always compare false. + $this->assertFalse(new RepeatedField(GPBType::INT32) == + new RepeatedField(GPBType::INT64)); + $this->assertFalse( + new RepeatedField(GPBType::MESSAGE, TestMessage::class) == + new RepeatedField(GPBType::MESSAGE, Sub::class)); + } } diff --git a/php/tests/GeneratedClassTest.php b/php/tests/GeneratedClassTest.php index f49c4e970c..90c1069ed3 100644 --- a/php/tests/GeneratedClassTest.php +++ b/php/tests/GeneratedClassTest.php @@ -1529,6 +1529,148 @@ class GeneratedClassTest extends TestBase $m->setOptionalString($values[0]); } + ######################################################### + # Test equality + ######################################################### + + public function testShallowEquality() + { + $m1 = new TestMessage([ + 'optional_int32' => -42, + 'optional_int64' => -43, + 'optional_uint32' => 42, + 'optional_uint64' => 43, + 'optional_sint32' => -44, + 'optional_sint64' => -45, + 'optional_fixed32' => 46, + 'optional_fixed64' => 47, + 'optional_sfixed32' => -46, + 'optional_sfixed64' => -47, + 'optional_float' => 1.5, + 'optional_double' => 1.6, + 'optional_bool' => true, + 'optional_string' => 'a', + 'optional_bytes' => 'bbbb', + 'optional_enum' => TestEnum::ONE, + ]); + $data = $m1->serializeToString(); + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $this->assertTrue($m1 == $m2); + + $m1->setOptionalInt32(1234); + $this->assertTrue($m1 != $m2); + } + + public function testDeepEquality() + { + $m1 = new TestMessage([ + 'optional_int32' => -42, + 'optional_int64' => -43, + 'optional_uint32' => 42, + 'optional_uint64' => 43, + 'optional_sint32' => -44, + 'optional_sint64' => -45, + 'optional_fixed32' => 46, + 'optional_fixed64' => 47, + 'optional_sfixed32' => -46, + 'optional_sfixed64' => -47, + 'optional_float' => 1.5, + 'optional_double' => 1.6, + 'optional_bool' => true, + 'optional_string' => 'a', + 'optional_bytes' => 'bbbb', + 'optional_enum' => TestEnum::ONE, + 'optional_message' => new Sub([ + 'a' => 33 + ]), + 'repeated_int32' => [-42, -52], + 'repeated_int64' => [-43, -53], + 'repeated_uint32' => [42, 52], + 'repeated_uint64' => [43, 53], + 'repeated_sint32' => [-44, -54], + 'repeated_sint64' => [-45, -55], + 'repeated_fixed32' => [46, 56], + 'repeated_fixed64' => [47, 57], + 'repeated_sfixed32' => [-46, -56], + 'repeated_sfixed64' => [-47, -57], + 'repeated_float' => [1.5, 2.5], + 'repeated_double' => [1.6, 2.6], + 'repeated_bool' => [true, false], + 'repeated_string' => ['a', 'c'], + 'repeated_bytes' => ['bbbb', 'dddd'], + 'repeated_enum' => [TestEnum::ZERO, TestEnum::ONE], + 'repeated_message' => [new Sub(['a' => 34]), + new Sub(['a' => 35])], + 'map_int32_int32' => [-62 => -62], + 'map_int64_int64' => [-63 => -63], + 'map_uint32_uint32' => [62 => 62], + 'map_uint64_uint64' => [63 => 63], + 'map_sint32_sint32' => [-64 => -64], + 'map_sint64_sint64' => [-65 => -65], + 'map_fixed32_fixed32' => [66 => 66], + 'map_fixed64_fixed64' => [67 => 67], + 'map_sfixed32_sfixed32' => [-68 => -68], + 'map_sfixed64_sfixed64' => [-69 => -69], + 'map_int32_float' => [1 => 3.5], + 'map_int32_double' => [1 => 3.6], + 'map_bool_bool' => [true => true], + 'map_string_string' => ['e' => 'e'], + 'map_int32_bytes' => [1 => 'ffff'], + 'map_int32_enum' => [1 => TestEnum::ONE], + 'map_int32_message' => [1 => new Sub(['a' => 36])], + ]); + $data = $m1->serializeToString(); + + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $this->assertTrue($m1 == $m2); + + # Nested sub-message is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getOptionalMessage()->setA(1234); + $this->assertTrue($m1 != $m2); + + # Repeated field element is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getRepeatedInt32()[0] = 1234; + $this->assertTrue($m1 != $m2); + + # Repeated field length is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getRepeatedInt32()[] = 1234; + $this->assertTrue($m1 != $m2); + + # SubMessage inside repeated field is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getRepeatedMessage()[0]->setA(1234); + $this->assertTrue($m1 != $m2); + + # Map value is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getMapInt32Int32()[-62] = 1234; + $this->assertTrue($m1 != $m2); + + # Map size is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getMapInt32Int32()[1234] = 1234; + $this->assertTrue($m1 != $m2); + + # SubMessage inside map field is checked. + $m2 = new TestMessage(); + $m2->mergeFromString($data); + $m2->getMapInt32Message()[1]->setA(1234); + $this->assertTrue($m1 != $m2); + + # TODO: what about unknown fields? + } + ######################################################### # Test no segfault when error happens ######################################################### diff --git a/php/tests/MapFieldTest.php b/php/tests/MapFieldTest.php index 577be681bf..4ed4b09cff 100644 --- a/php/tests/MapFieldTest.php +++ b/php/tests/MapFieldTest.php @@ -479,6 +479,35 @@ class MapFieldTest extends \PHPUnit\Framework\TestCase { $m->setMapInt32Message($values); } + ######################################################### + # Test equality + ######################################################### + + public function testEquality() + { + $map = new MapField(GPBType::INT32, GPBType::INT32); + $map2 = new MapField(GPBType::INT32, GPBType::INT32); + + $this->assertTrue($map == $map2); + + $map[1] = 2; + + $this->assertFalse($map == $map2); + + $map2[1] = 2; + + $this->assertTrue($map == $map2); + + // Arrays of different types always compare false. + $this->assertFalse(new MapField(GPBType::INT32, GPBType::INT32) == + new MapField(GPBType::INT32, GPBType::INT64)); + $this->assertFalse(new MapField(GPBType::INT32, GPBType::INT32) == + new MapField(GPBType::INT64, GPBType::INT32)); + $this->assertFalse( + new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class) == + new MapField(GPBType::INT32, GPBType::MESSAGE, Sub::class)); + } + ######################################################### # Test memory leak ######################################################### diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl index a1603323af..a95008501b 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -51,9 +51,9 @@ def protobuf_deps(): if not native.existing_rule("rules_proto"): http_archive( name = "rules_proto", - sha256 = "602e7161d9195e50246177e7c55b2f39950a9cf7366f74ed5f22fd45750cd208", - strip_prefix = "rules_proto-97d8af4dc474595af3900dd85cb3a29ad28cc313", - urls = ["https://github.com/bazelbuild/rules_proto/archive/97d8af4dc474595af3900dd85cb3a29ad28cc313.tar.gz"], + sha256 = "aa1ee19226f707d44bee44c720915199c20c84a23318bb0597ed4e5c873ccbd5", + strip_prefix = "rules_proto-40298556293ae502c66579620a7ce867d5f57311", + urls = ["https://github.com/bazelbuild/rules_proto/archive/40298556293ae502c66579620a7ce867d5f57311.tar.gz"], ) if not native.existing_rule("rules_python"): diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py index ecd28eefb1..c35b00d9fb 100644 --- a/python/google/protobuf/internal/containers.py +++ b/python/google/protobuf/internal/containers.py @@ -629,7 +629,8 @@ class MessageMap(MutableMapping): return repr(self._values) def MergeFrom(self, other): - for key in other: + # pylint: disable=protected-access + for key in other._values: # According to documentation: "When parsing from the wire or when merging, # if there are duplicate map keys the last key seen is used". if key in self: diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index a4d62a85b1..feff228fb6 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -2107,6 +2107,11 @@ class Proto3Test(unittest.TestCase): self.assertEqual(msg.map_int32_foreign_message[222].d, 20) self.assertNotEqual(msg.map_int32_foreign_message[222].c, 123) + # Merge a dict to map field is not accepted + with self.assertRaises(AttributeError): + m1.map_int32_all_types.MergeFrom( + {1: unittest_proto3_arena_pb2.TestAllTypes()}) + def testMergeFromBadType(self): msg = map_unittest_pb2.TestMap() with self.assertRaisesRegexp( diff --git a/python/google/protobuf/pyext/map_container.cc b/python/google/protobuf/pyext/map_container.cc index 86b8720240..a0ee16fe86 100644 --- a/python/google/protobuf/pyext/map_container.cc +++ b/python/google/protobuf/pyext/map_container.cc @@ -339,6 +339,11 @@ PyObject* GetEntryClass(PyObject* _self) { PyObject* MapReflectionFriend::MergeFrom(PyObject* _self, PyObject* arg) { MapContainer* self = GetMap(_self); + if (!PyObject_TypeCheck(arg, ScalarMapContainer_Type) && + !PyObject_TypeCheck(arg, MessageMapContainer_Type)) { + PyErr_SetString(PyExc_AttributeError, "Not a map field"); + return nullptr; + } MapContainer* other_map = GetMap(arg); Message* message = self->GetMutableMessage(); const Message* other_message = other_map->parent->message; diff --git a/python/protobuf_distutils/README.md b/python/protobuf_distutils/README.md new file mode 100644 index 0000000000..2989b2ad54 --- /dev/null +++ b/python/protobuf_distutils/README.md @@ -0,0 +1,106 @@ +# Python setuptools extension + +This is an extension for Python setuptools which uses an installed protobuf +compiler (`protoc`) to generate Python sources. + +## Installing + +To use this extension, it needs to be installed so it can be imported by other +projects' setup.py. + +```shell +$ python setup.py build +$ python -m pip install . +``` + +(If you want to test changes to the extension, you can use `python setup.py +develop`.) + +## Usage + +### Example setup.py configuration + +```python +from setuptools import setup +setup( + # ... + name='example_project', + + # Require this package, but only for setup (not installation): + setup_requires=['protobuf_distutils'], + + options={ + # See below for details. + 'generate_py_protobufs': { + 'source_dir': 'path/to/protos', + 'extra_proto_paths': ['path/to/other/project/protos'], + 'output_dir': 'path/to/project/sources', # default '.' + 'proto_files': ['relative/path/to/just_this_file.proto'], + 'protoc': 'path/to/protoc.exe', + }, + }, +) +``` + +### Example build invocation + +These steps will generate protobuf sources so they are included when building +and installing `example_project` (see above): + +```shell +$ python setup.py generate_py_protobufs +$ python setup.py build +$ python -m pip install . +``` + +## Options + +- `source_dir`: + + This is the directory holding .proto files to be processed. + + The default behavior is to generate sources for all .proto files found under + `source_dir`, recursively. This behavior can be controlled with options below. + +- `proto_root_path`: + + This is the root path for resolving imports in source .proto files. + + The default is the shortest prefix of `source_dir` among `[source_dir] + + self.extra_proto_paths`. + +- `extra_proto_paths`: + + Specifies additional paths that should be used to find imports, in + addition to `source_dir`. + + This option can be used to specify the path to other protobuf sources, + which are imported by files under `source_dir`. No Python code will + be generated for .proto files under `extra_proto_paths`. + +- `output_dir`: + + Specifies where generated code should be placed. + + Typically, this should be the root package that generated Python modules + should be below. + + The generated files will be placed under `output_dir` according to the + relative source paths under `proto_root_path`. For example, the source file + `${proto_root_path}/subdir/message.proto` will be generated as the Python + module `${output_dir}/subdir/message_pb2.py`. + +- `proto_files`: + + A list of strings, specific .proto file paths for generating code, instead of + searching for all .proto files under `source_path`. + + These paths are relative to `source_dir`. For example, to generate code + for just `${source_dir}/subdir/message.proto`, specify + `['subdir/message.proto']`. + +- `protoc`: + + By default, the protoc binary (the Protobuf compiler) is found by + searching the environment path. To use a specific protoc binary, its + path can be specified. diff --git a/python/setup.py b/python/setup.py index 0a8d335090..39eb18d4bb 100755 --- a/python/setup.py +++ b/python/setup.py @@ -2,6 +2,7 @@ # # See README for usage instructions. from distutils import util +import fnmatch import glob import os import pkg_resources @@ -144,6 +145,18 @@ class build_py(_build_py): # _build_py is an old-style class, so super() doesn't work. _build_py.run(self) + def find_package_modules(self, package, package_dir): + exclude = ( + "*test*", + "google/protobuf/internal/*_pb2.py", + "google/protobuf/internal/_parameterized.py", + "google/protobuf/pyext/python_pb2.py", + ) + modules = _build_py.find_package_modules(self, package, package_dir) + return [(pkg, mod, fil) for (pkg, mod, fil) in modules + if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)] + + class test_conformance(_build_py): target = 'test_python' def run(self): @@ -271,6 +284,7 @@ if __name__ == '__main__': packages=find_packages( exclude=[ 'import_test_package', + 'protobuf_distutils', ], ), test_suite='google.protobuf.internal', diff --git a/src/Makefile.am b/src/Makefile.am index b8b1479fe9..855dd8908d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -68,7 +68,6 @@ nobase_include_HEADERS = \ google/protobuf/stubs/bytestream.h \ google/protobuf/stubs/casts.h \ google/protobuf/stubs/common.h \ - google/protobuf/stubs/fastmem.h \ google/protobuf/stubs/hash.h \ google/protobuf/stubs/logging.h \ google/protobuf/stubs/macros.h \ @@ -104,7 +103,6 @@ nobase_include_HEADERS = \ google/protobuf/generated_message_util.h \ google/protobuf/has_bits.h \ google/protobuf/implicit_weak_message.h \ - google/protobuf/inlined_string_field.h \ google/protobuf/io/io_win32.h \ google/protobuf/map_entry.h \ google/protobuf/map_entry_lite.h \ @@ -202,6 +200,7 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/stubs/time.h \ google/protobuf/any_lite.cc \ google/protobuf/arena.cc \ + google/protobuf/arenastring.cc \ google/protobuf/extension_set.cc \ google/protobuf/generated_enum_util.cc \ google/protobuf/generated_message_util.cc \ diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc index ebe9ba7e0a..d22d64d2e3 100644 --- a/src/google/protobuf/any.cc +++ b/src/google/protobuf/any.cc @@ -51,9 +51,8 @@ void AnyMetadata::PackFrom(const Message& message, &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyString(), GetTypeUrl(message.GetDescriptor()->full_name(), type_url_prefix), nullptr); - message.SerializeToString(value_->Mutable( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), - nullptr)); + message.SerializeToString( + value_->Mutable(ArenaStringPtr::EmptyDefault{}, nullptr)); } bool AnyMetadata::UnpackTo(Message* message) const { diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 3170748106..79acf7b735 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -112,12 +112,12 @@ Any::Any(const Any& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_type_url().empty()) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_type_url(), + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), GetArena()); } value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_value().empty()) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_value(), + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.Any) @@ -162,8 +162,8 @@ void Any::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + type_url_.ClearToEmpty(); + value_.ClearToEmpty(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index ec18f3aeb7..7c732564a6 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -272,7 +271,7 @@ class PROTOBUF_EXPORT Any PROTOBUF_FINAL : // string type_url = 1; inline void Any::clear_type_url() { - type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + type_url_.ClearToEmpty(); } inline const std::string& Any::type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Any.type_url) @@ -291,31 +290,30 @@ inline const std::string& Any::_internal_type_url() const { } inline void Any::_internal_set_type_url(const std::string& value) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Any::set_type_url(std::string&& value) { type_url_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.type_url) } inline void Any::set_type_url(const char* value) { GOOGLE_DCHECK(value != nullptr); - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url) } inline void Any::set_type_url(const char* value, size_t size) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.type_url) } inline std::string* Any::_internal_mutable_type_url() { - return type_url_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Any::release_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Any.type_url) @@ -334,7 +332,7 @@ inline void Any::set_allocated_type_url(std::string* type_url) { // bytes value = 2; inline void Any::clear_value() { - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + value_.ClearToEmpty(); } inline const std::string& Any::value() const { // @@protoc_insertion_point(field_get:google.protobuf.Any.value) @@ -353,31 +351,30 @@ inline const std::string& Any::_internal_value() const { } inline void Any::_internal_set_value(const std::string& value) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Any::set_value(std::string&& value) { value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Any.value) } inline void Any::set_value(const char* value) { GOOGLE_DCHECK(value != nullptr); - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value) } inline void Any::set_value(const void* value, size_t size) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Any.value) } inline std::string* Any::_internal_mutable_value() { - return value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Any::release_value() { // @@protoc_insertion_point(field_release:google.protobuf.Any.value) diff --git a/src/google/protobuf/any_lite.cc b/src/google/protobuf/any_lite.cc index 206b01fbd1..7501969da5 100644 --- a/src/google/protobuf/any_lite.cc +++ b/src/google/protobuf/any_lite.cc @@ -61,8 +61,8 @@ void AnyMetadata::InternalPackFrom(const MessageLite& message, StringPiece type_name) { type_url_->Set(&::google::protobuf::internal::GetEmptyString(), GetTypeUrl(type_name, type_url_prefix), nullptr); - message.SerializeToString(value_->Mutable( - &::google::protobuf::internal::GetEmptyStringAlreadyInited(), nullptr)); + message.SerializeToString( + value_->Mutable(ArenaStringPtr::EmptyDefault{}, nullptr)); } bool AnyMetadata::InternalUnpackTo(StringPiece type_name, diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index f8e20a11d9..17c8e3309d 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -204,12 +204,12 @@ Api::Api(const Api& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_version().empty()) { - version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_version(), + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_version(), GetArena()); } if (from._internal_has_source_context()) { @@ -267,8 +267,8 @@ void Api::Clear() { methods_.Clear(); options_.Clear(); mixins_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); - version_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); + version_.ClearToEmpty(); if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } @@ -614,17 +614,17 @@ Method::Method(const Method& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_request_type_url().empty()) { - request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_request_type_url(), + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_request_type_url(), GetArena()); } response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_response_type_url().empty()) { - response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_response_type_url(), + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_response_type_url(), GetArena()); } ::memcpy(&request_streaming_, &from.request_streaming_, @@ -678,9 +678,9 @@ void Method::Clear() { (void) cached_has_bits; options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); - request_type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); - response_type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); + request_type_url_.ClearToEmpty(); + response_type_url_.ClearToEmpty(); ::memset(&request_streaming_, 0, static_cast( reinterpret_cast(&syntax_) - reinterpret_cast(&request_streaming_)) + sizeof(syntax_)); @@ -1008,12 +1008,12 @@ Mixin::Mixin(const Mixin& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_root().empty()) { - root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_root(), + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_root(), GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin) @@ -1058,8 +1058,8 @@ void Mixin::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); - root_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); + root_.ClearToEmpty(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index f37ea8c2f7..b47f1df0f3 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -732,7 +731,7 @@ class PROTOBUF_EXPORT Mixin PROTOBUF_FINAL : // string name = 1; inline void Api::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); } inline const std::string& Api::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.name) @@ -751,31 +750,30 @@ inline const std::string& Api::_internal_name() const { } inline void Api::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Api::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Api.name) } inline void Api::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name) } inline void Api::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.name) } inline std::string* Api::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Api::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Api.name) @@ -869,7 +867,7 @@ Api::options() const { // string version = 4; inline void Api::clear_version() { - version_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + version_.ClearToEmpty(); } inline const std::string& Api::version() const { // @@protoc_insertion_point(field_get:google.protobuf.Api.version) @@ -888,31 +886,30 @@ inline const std::string& Api::_internal_version() const { } inline void Api::_internal_set_version(const std::string& value) { - version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Api::set_version(std::string&& value) { version_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Api.version) } inline void Api::set_version(const char* value) { GOOGLE_DCHECK(value != nullptr); - version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version) } inline void Api::set_version(const char* value, size_t size) { - version_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + version_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Api.version) } inline std::string* Api::_internal_mutable_version() { - return version_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return version_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Api::release_version() { // @@protoc_insertion_point(field_release:google.protobuf.Api.version) @@ -1071,7 +1068,7 @@ inline void Api::set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value) { // string name = 1; inline void Method::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); } inline const std::string& Method::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.name) @@ -1090,31 +1087,30 @@ inline const std::string& Method::_internal_name() const { } inline void Method::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Method::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Method.name) } inline void Method::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name) } inline void Method::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.name) } inline std::string* Method::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Method::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Method.name) @@ -1133,7 +1129,7 @@ inline void Method::set_allocated_name(std::string* name) { // string request_type_url = 2; inline void Method::clear_request_type_url() { - request_type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + request_type_url_.ClearToEmpty(); } inline const std::string& Method::request_type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.request_type_url) @@ -1152,31 +1148,30 @@ inline const std::string& Method::_internal_request_type_url() const { } inline void Method::_internal_set_request_type_url(const std::string& value) { - request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Method::set_request_type_url(std::string&& value) { request_type_url_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Method.request_type_url) } inline void Method::set_request_type_url(const char* value) { GOOGLE_DCHECK(value != nullptr); - request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url) } inline void Method::set_request_type_url(const char* value, size_t size) { - request_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + request_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.request_type_url) } inline std::string* Method::_internal_mutable_request_type_url() { - return request_type_url_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return request_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Method::release_request_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Method.request_type_url) @@ -1215,7 +1210,7 @@ inline void Method::set_request_streaming(bool value) { // string response_type_url = 4; inline void Method::clear_response_type_url() { - response_type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + response_type_url_.ClearToEmpty(); } inline const std::string& Method::response_type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Method.response_type_url) @@ -1234,31 +1229,30 @@ inline const std::string& Method::_internal_response_type_url() const { } inline void Method::_internal_set_response_type_url(const std::string& value) { - response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Method::set_response_type_url(std::string&& value) { response_type_url_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Method.response_type_url) } inline void Method::set_response_type_url(const char* value) { GOOGLE_DCHECK(value != nullptr); - response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url) } inline void Method::set_response_type_url(const char* value, size_t size) { - response_type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + response_type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Method.response_type_url) } inline std::string* Method::_internal_mutable_response_type_url() { - return response_type_url_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return response_type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Method::release_response_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Method.response_type_url) @@ -1357,7 +1351,7 @@ inline void Method::set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value) { // string name = 1; inline void Mixin::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); } inline const std::string& Mixin::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name) @@ -1376,31 +1370,30 @@ inline const std::string& Mixin::_internal_name() const { } inline void Mixin::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Mixin::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Mixin.name) } inline void Mixin::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name) } inline void Mixin::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name) } inline std::string* Mixin::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Mixin::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Mixin.name) @@ -1419,7 +1412,7 @@ inline void Mixin::set_allocated_name(std::string* name) { // string root = 2; inline void Mixin::clear_root() { - root_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + root_.ClearToEmpty(); } inline const std::string& Mixin::root() const { // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root) @@ -1438,31 +1431,30 @@ inline const std::string& Mixin::_internal_root() const { } inline void Mixin::_internal_set_root(const std::string& value) { - root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Mixin::set_root(std::string&& value) { root_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Mixin.root) } inline void Mixin::set_root(const char* value) { GOOGLE_DCHECK(value != nullptr); - root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root) } inline void Mixin::set_root(const char* value, size_t size) { - root_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + root_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root) } inline std::string* Mixin::_internal_mutable_root() { - return root_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return root_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Mixin::release_root() { // @@protoc_insertion_point(field_release:google.protobuf.Mixin.root) diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc index 13e11b51aa..fce59b2545 100644 --- a/src/google/protobuf/arena.cc +++ b/src/google/protobuf/arena.cc @@ -49,6 +49,10 @@ namespace google { namespace protobuf { namespace internal { +const size_t ArenaImpl::kBlockHeaderSize; +const size_t ArenaImpl::kSerialArenaSize; +const size_t ArenaImpl::kOptionsSize; + std::atomic ArenaImpl::lifecycle_id_generator_; #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) @@ -67,43 +71,143 @@ PROTOBUF_THREAD_LOCAL ArenaImpl::ThreadCache ArenaImpl::thread_cache_ = {-1, NULL}; #endif -void ArenaImpl::Init() { - lifecycle_id_ = - lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed); +void ArenaFree(void* object, size_t size) { +#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) + ::operator delete(object, size); +#else + (void)size; + ::operator delete(object); +#endif +} + +ArenaImpl::ArenaImpl(const ArenaOptions& options) { + ArenaMetricsCollector* collector = nullptr; + bool record_allocs = false; + if (options.make_metrics_collector != nullptr) { + collector = (*options.make_metrics_collector)(); + record_allocs = (collector && collector->RecordAllocs()); + } + + // Get memory where we can store non-default options if needed. + // Use supplied initial_block if it is large enough. + size_t min_block_size = kOptionsSize + kBlockHeaderSize + kSerialArenaSize; + char* mem = options.initial_block; + size_t mem_size = options.initial_block_size; + GOOGLE_DCHECK_EQ(reinterpret_cast(mem) & 7, 0); + if (mem == nullptr || mem_size < min_block_size) { + // Supplied initial block is not big enough. + mem_size = std::max(min_block_size, options.start_block_size); + mem = reinterpret_cast((*options.block_alloc)(mem_size)); + } + + // Create the special block. + const bool special = true; + const bool user_owned = (mem == options.initial_block); + auto block = new (mem) Block(mem_size, nullptr, special, user_owned); + + // Options occupy the beginning of the initial block. + options_ = new (block->Pointer(block->pos())) Options; +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(options_, kOptionsSize); +#endif // ADDRESS_SANITIZER + options_->start_block_size = options.start_block_size; + options_->max_block_size = options.max_block_size; + options_->block_alloc = options.block_alloc; + options_->block_dealloc = options.block_dealloc; + options_->metrics_collector = collector; + block->set_pos(block->pos() + kOptionsSize); + + Init(record_allocs); + SetInitialBlock(block); +} + +void ArenaImpl::Init(bool record_allocs) { + // We store "record_allocs" in the low bit of lifecycle_id_. + auto id = lifecycle_id_generator_.fetch_add(1, std::memory_order_relaxed); + lifecycle_id_ = (id << 1) | (record_allocs ? 1 : 0); hint_.store(nullptr, std::memory_order_relaxed); threads_.store(nullptr, std::memory_order_relaxed); + space_allocated_.store(0, std::memory_order_relaxed); +} - if (initial_block_) { - // Thread which calls Init() owns the first block. This allows the - // single-threaded case to allocate on the first block without having to - // perform atomic operations. - new (initial_block_) Block(options_.initial_block_size, NULL); - SerialArena* serial = - SerialArena::New(initial_block_, &thread_cache(), this); - serial->set_next(NULL); - threads_.store(serial, std::memory_order_relaxed); - space_allocated_.store(options_.initial_block_size, - std::memory_order_relaxed); - CacheSerialArena(serial); - } else { - space_allocated_.store(0, std::memory_order_relaxed); - } +void ArenaImpl::SetInitialBlock(Block* block) { + // Calling thread owns the first block. This allows the single-threaded case + // to allocate on the first block without having to perform atomic operations. + SerialArena* serial = SerialArena::New(block, &thread_cache(), this); + serial->set_next(NULL); + threads_.store(serial, std::memory_order_relaxed); + space_allocated_.store(block->size(), std::memory_order_relaxed); + CacheSerialArena(serial); } ArenaImpl::~ArenaImpl() { // Have to do this in a first pass, because some of the destructors might // refer to memory in other blocks. CleanupList(); - FreeBlocks(); + + ArenaMetricsCollector* collector = nullptr; + auto deallocator = &ArenaFree; + if (options_) { + collector = options_->metrics_collector; + deallocator = options_->block_dealloc; + } + + PerBlock([deallocator](Block* b) { +#ifdef ADDRESS_SANITIZER + // This memory was provided by the underlying allocator as unpoisoned, so + // return it in an unpoisoned state. + ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size()); +#endif // ADDRESS_SANITIZER + if (!b->user_owned()) { + (*deallocator)(b, b->size()); + } + }); + + if (collector) { + collector->OnDestroy(SpaceAllocated()); + } } uint64 ArenaImpl::Reset() { + if (options_ && options_->metrics_collector) { + options_->metrics_collector->OnReset(SpaceAllocated()); + } + // Have to do this in a first pass, because some of the destructors might // refer to memory in other blocks. CleanupList(); - uint64 space_allocated = FreeBlocks(); - Init(); + // Discard all blocks except the special block (if present). + uint64 space_allocated = 0; + Block* special_block = nullptr; + auto deallocator = (options_ ? options_->block_dealloc : &ArenaFree); + PerBlock([&space_allocated, &special_block, deallocator](Block* b) { + space_allocated += b->size(); +#ifdef ADDRESS_SANITIZER + // This memory was provided by the underlying allocator as unpoisoned, so + // return it in an unpoisoned state. + ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size()); +#endif // ADDRESS_SANITIZER + if (!b->special()) { + (*deallocator)(b, b->size()); + } else { + // Prepare special block for reuse. + // Note: if options_ is present, it occupies the beginning of the + // block and therefore pos is advanced past it. + GOOGLE_DCHECK(special_block == nullptr); + special_block = b; + } + }); + + Init(record_allocs()); + if (special_block != nullptr) { + // next() should still be nullptr since we are using a stack discipline, but + // clear it anyway to reduce fragility. + GOOGLE_DCHECK_EQ(special_block->next(), nullptr); + special_block->clear_next(); + special_block->set_pos(kBlockHeaderSize + (options_ ? kOptionsSize : 0)); + SetInitialBlock(special_block); + } return space_allocated; } @@ -111,23 +215,21 @@ ArenaImpl::Block* ArenaImpl::NewBlock(Block* last_block, size_t min_bytes) { size_t size; if (last_block) { // Double the current block size, up to a limit. - size = std::min(2 * last_block->size(), options_.max_block_size); + auto max_size = options_ ? options_->max_block_size : kDefaultMaxBlockSize; + size = std::min(2 * last_block->size(), max_size); } else { - size = options_.start_block_size; + size = options_ ? options_->start_block_size : kDefaultStartBlockSize; } // Verify that min_bytes + kBlockHeaderSize won't overflow. GOOGLE_CHECK_LE(min_bytes, std::numeric_limits::max() - kBlockHeaderSize); size = std::max(size, kBlockHeaderSize + min_bytes); - void* mem = options_.block_alloc(size); - Block* b = new (mem) Block(size, last_block); + void* mem = options_ ? (*options_->block_alloc)(size) : ::operator new(size); + Block* b = new (mem) Block(size, last_block, false, false); space_allocated_.fetch_add(size, std::memory_order_relaxed); return b; } -ArenaImpl::Block::Block(size_t size, Block* next) - : next_(next), pos_(kBlockHeaderSize), size_(size) {} - PROTOBUF_NOINLINE void ArenaImpl::SerialArena::AddCleanupFallback(void* elem, void (*cleanup)(void*)) { @@ -207,6 +309,10 @@ uint64 ArenaImpl::SpaceUsed() const { for (; serial; serial = serial->next()) { space_used += serial->SpaceUsed(); } + // Remove the overhead of Options structure, if any. + if (options_) { + space_used -= kOptionsSize; + } return space_used; } @@ -222,53 +328,6 @@ uint64 ArenaImpl::SerialArena::SpaceUsed() const { return space_used; } -uint64 ArenaImpl::FreeBlocks() { - uint64 space_allocated = 0; - // By omitting an Acquire barrier we ensure that any user code that doesn't - // properly synchronize Reset() or the destructor will throw a TSAN warning. - SerialArena* serial = threads_.load(std::memory_order_relaxed); - - while (serial) { - // This is inside a block we are freeing, so we need to read it now. - SerialArena* next = serial->next(); - space_allocated += ArenaImpl::SerialArena::Free(serial, initial_block_, - options_.block_dealloc); - // serial is dead now. - serial = next; - } - - return space_allocated; -} - -uint64 ArenaImpl::SerialArena::Free(ArenaImpl::SerialArena* serial, - Block* initial_block, - void (*block_dealloc)(void*, size_t)) { - uint64 space_allocated = 0; - - // We have to be careful in this function, since we will be freeing the Block - // that contains this SerialArena. Be careful about accessing |serial|. - - for (Block* b = serial->head_; b;) { - // This is inside the block we are freeing, so we need to read it now. - Block* next_block = b->next(); - space_allocated += (b->size()); - -#ifdef ADDRESS_SANITIZER - // This memory was provided by the underlying allocator as unpoisoned, so - // return it in an unpoisoned state. - ASAN_UNPOISON_MEMORY_REGION(b->Pointer(0), b->size()); -#endif // ADDRESS_SANITIZER - - if (b != initial_block) { - block_dealloc(b, b->size()); - } - - b = next_block; - } - - return space_allocated; -} - void ArenaImpl::CleanupList() { // By omitting an Acquire barrier we ensure that any user code that doesn't // properly synchronize Reset() or the destructor will throw a TSAN warning. @@ -307,11 +366,10 @@ void ArenaImpl::SerialArena::CleanupListFallback() { ArenaImpl::SerialArena* ArenaImpl::SerialArena::New(Block* b, void* owner, ArenaImpl* arena) { - GOOGLE_DCHECK_EQ(b->pos(), kBlockHeaderSize); // Should be a fresh block - GOOGLE_DCHECK_LE(kBlockHeaderSize + kSerialArenaSize, b->size()); - SerialArena* serial = - reinterpret_cast(b->Pointer(kBlockHeaderSize)); - b->set_pos(kBlockHeaderSize + kSerialArenaSize); + auto pos = b->pos(); + GOOGLE_DCHECK_LE(pos + kSerialArenaSize, b->size()); + SerialArena* serial = reinterpret_cast(b->Pointer(pos)); + b->set_pos(pos + kSerialArenaSize); serial->arena_ = arena; serial->owner_ = owner; serial->head_ = b; @@ -350,6 +408,8 @@ ArenaImpl::SerialArena* ArenaImpl::GetSerialArenaFallback(void* me) { return serial; } +ArenaMetricsCollector::~ArenaMetricsCollector() {} + } // namespace internal PROTOBUF_FUNC_ALIGN(32) @@ -357,25 +417,5 @@ void* Arena::AllocateAlignedNoHook(size_t n) { return impl_.AllocateAligned(n); } -void Arena::CallDestructorHooks() { - uint64 space_allocated = impl_.SpaceAllocated(); - // Call the reset hook - if (on_arena_reset_ != NULL) { - on_arena_reset_(this, hooks_cookie_, space_allocated); - } - - // Call the destruction hook - if (on_arena_destruction_ != NULL) { - on_arena_destruction_(this, hooks_cookie_, space_allocated); - } -} - -void Arena::OnArenaAllocation(const std::type_info* allocated_type, - size_t n) const { - if (on_arena_allocation_ != NULL) { - on_arena_allocation_(allocated_type, n, hooks_cookie_); - } -} - } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 038553c83f..7c5c7d00bd 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -102,15 +102,6 @@ template void arena_delete_object(void* object) { delete reinterpret_cast(object); } -inline void arena_free(void* object, size_t size) { -#if defined(__GXX_DELETE_WITH_SIZE__) || defined(__cpp_sized_deallocation) - ::operator delete(object, size); -#else - (void)size; - ::operator delete(object); -#endif -} - } // namespace internal // ArenaOptions provides optional additional parameters to arena construction @@ -152,43 +143,27 @@ struct ArenaOptions { initial_block(NULL), initial_block_size(0), block_alloc(&::operator new), - block_dealloc(&internal::arena_free), - on_arena_init(NULL), - on_arena_reset(NULL), - on_arena_destruction(NULL), - on_arena_allocation(NULL) {} + block_dealloc(&internal::ArenaFree), + make_metrics_collector(nullptr) {} private: - // Hooks for adding external functionality such as user-specific metrics - // collection, specific debugging abilities, etc. - // Init hook (if set) will always be called at Arena init time. Init hook may - // return a pointer to a cookie to be stored in the arena. Reset and - // destruction hooks will then be called with the same cookie pointer. This - // allows us to save an external object per arena instance and use it on the - // other hooks (Note: If init hook returns NULL, the other hooks will NOT be - // called on this arena instance). - // on_arena_reset and on_arena_destruction also receive the space used in the - // arena just before the reset. - void* (*on_arena_init)(Arena* arena); - void (*on_arena_reset)(Arena* arena, void* cookie, uint64 space_used); - void (*on_arena_destruction)(Arena* arena, void* cookie, uint64 space_used); - - // type_info is promised to be static - its lifetime extends to - // match program's lifetime (It is given by typeid operator). - // Note: typeid(void) will be passed as allocated_type every time we - // intentionally want to avoid monitoring an allocation. (i.e. internal - // allocations for managing the arena) - void (*on_arena_allocation)(const std::type_info* allocated_type, - uint64 alloc_size, void* cookie); + // If make_metrics_collector is not nullptr, it will be called at Arena init + // time. It may return a pointer to a collector instance that will be notified + // of interesting events related to the arena. + internal::ArenaMetricsCollector* (*make_metrics_collector)(); // Constants define default starting block size and max block size for // arena allocator behavior -- see descriptions above. - static const size_t kDefaultStartBlockSize = 256; - static const size_t kDefaultMaxBlockSize = 8192; + static const size_t kDefaultStartBlockSize = + internal::ArenaImpl::kDefaultStartBlockSize; + static const size_t kDefaultMaxBlockSize = + internal::ArenaImpl::kDefaultMaxBlockSize; friend void arena_metrics::EnableArenaMetrics(ArenaOptions*); + friend class Arena; friend class ArenaOptionsTestFriend; + friend class internal::ArenaImpl; }; // Support for non-RTTI environments. (The metrics hooks API uses type @@ -246,11 +221,20 @@ struct ArenaOptions { // should not rely on this protocol. class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { public: - // Arena constructor taking custom options. See ArenaOptions below for + // Default constructor with sensible default options, tuned for average + // use-cases. + inline Arena() : impl_() {} + + // Construct an arena with default options, except for the supplied + // initial block. It is more efficient to use this constructor + // instead of passing ArenaOptions if the only configuration needed + // by the caller is supplying an initial block. + inline Arena(char* initial_block, size_t initial_block_size) + : impl_(initial_block, initial_block_size) {} + + // Arena constructor taking custom options. See ArenaOptions above for // descriptions of the options available. - explicit Arena(const ArenaOptions& options) : impl_(options) { - Init(options); - } + explicit Arena(const ArenaOptions& options) : impl_(options) {} // Block overhead. Use this as a guide for how much to over-allocate the // initial block if you want an allocation of size N to fit inside it. @@ -261,27 +245,10 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { static const size_t kBlockOverhead = internal::ArenaImpl::kBlockHeaderSize + internal::ArenaImpl::kSerialArenaSize; - // Default constructor with sensible default options, tuned for average - // use-cases. - Arena() : impl_(ArenaOptions()) { Init(ArenaOptions()); } + inline ~Arena() {} - ~Arena() { - if (hooks_cookie_) { - CallDestructorHooks(); - } - } - - void Init(const ArenaOptions& options) { - on_arena_allocation_ = options.on_arena_allocation; - on_arena_reset_ = options.on_arena_reset; - on_arena_destruction_ = options.on_arena_destruction; - // Call the initialization hook - if (options.on_arena_init != NULL) { - hooks_cookie_ = options.on_arena_init(this); - } else { - hooks_cookie_ = NULL; - } - } + // TODO(protobuf-team): Fix callers to use constructor and delete this method. + void Init(const ArenaOptions&) {} // API to create proto2 message objects on the arena. If the arena passed in // is NULL, then a heap allocated object is returned. Type T must be a message @@ -362,13 +329,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // Any objects allocated on this arena are unusable after this call. It also // returns the total space used by the arena which is the sums of the sizes // of the allocated blocks. This method is not thread-safe. - PROTOBUF_NOINLINE uint64 Reset() { - // Call the reset hook - if (on_arena_reset_ != NULL) { - on_arena_reset_(this, hooks_cookie_, impl_.SpaceAllocated()); - } - return impl_.Reset(); - } + uint64 Reset() { return impl_.Reset(); } // Adds |object| to a list of heap-allocated objects to be freed with |delete| // when the arena is destroyed or reset. @@ -515,22 +476,17 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { } } - void CallDestructorHooks(); - void OnArenaAllocation(const std::type_info* allocated_type, size_t n) const; inline void AllocHook(const std::type_info* allocated_type, size_t n) const { - if (PROTOBUF_PREDICT_FALSE(hooks_cookie_ != NULL)) { - OnArenaAllocation(allocated_type, n); - } + impl_.RecordAlloc(allocated_type, n); } - // Allocate and also optionally call on_arena_allocation callback with the - // allocated type info when the hooks are in place in ArenaOptions and - // the cookie is not null. + // Allocate and also optionally call collector with the allocated type info + // when allocation recording is enabled. template PROTOBUF_ALWAYS_INLINE void* AllocateInternal(bool skip_explicit_ownership) { static_assert(alignof(T) <= 8, "T is overaligned, see b/151247138"); const size_t n = internal::AlignUpTo8(sizeof(T)); - AllocHook(RTTI_TYPE_ID(T), n); + impl_.RecordAlloc(RTTI_TYPE_ID(T), n); // Monitor allocation if needed. if (skip_explicit_ownership) { return AllocateAlignedNoHook(n); @@ -593,7 +549,7 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { << "Requested size is too large to fit into size_t."; const size_t n = internal::AlignUpTo8(sizeof(T) * num_elements); // Monitor allocation if needed. - AllocHook(RTTI_TYPE_ID(T), n); + impl_.RecordAlloc(RTTI_TYPE_ID(T), n); return static_cast(AllocateAlignedNoHook(n)); } @@ -687,7 +643,6 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { // For friends of arena. void* AllocateAligned(size_t n) { - AllocHook(NULL, n); return AllocateAlignedNoHook(internal::AlignUpTo8(n)); } template @@ -706,15 +661,6 @@ class PROTOBUF_EXPORT PROTOBUF_ALIGNAS(8) Arena final { internal::ArenaImpl impl_; - void (*on_arena_allocation_)(const std::type_info* allocated_type, - uint64 alloc_size, void* cookie); - void (*on_arena_reset_)(Arena* arena, void* cookie, uint64 space_used); - void (*on_arena_destruction_)(Arena* arena, void* cookie, uint64 space_used); - - // The arena may save a cookie it receives from the external on_init hook - // and then use it when calling the on_reset and on_destruction hooks. - void* hooks_cookie_; - template friend class internal::GenericTypeHandler; friend struct internal::ArenaStringPtr; // For AllocateAligned. diff --git a/src/google/protobuf/arena_impl.h b/src/google/protobuf/arena_impl.h index 2f8d343fd3..56ef7e1a55 100644 --- a/src/google/protobuf/arena_impl.h +++ b/src/google/protobuf/arena_impl.h @@ -48,6 +48,9 @@ namespace google { namespace protobuf { + +struct ArenaOptions; + namespace internal { inline size_t AlignUpTo8(size_t n) { @@ -57,6 +60,36 @@ inline size_t AlignUpTo8(size_t n) { using LifecycleId = int64_t; +void PROTOBUF_EXPORT ArenaFree(void* object, size_t size); + +// MetricsCollector collects stats for a particular arena. +class PROTOBUF_EXPORT ArenaMetricsCollector { + public: + virtual ~ArenaMetricsCollector(); + + // Invoked when the arena is about to be destroyed. This method will + // typically finalize any metric collection and delete the collector. + // space_allocated is the space used by the arena. + virtual void OnDestroy(uint64 space_allocated) = 0; + + // OnReset() is called when the associated arena is reset. + // space_allocated is the space used by the arena just before the reset. + virtual void OnReset(uint64 space_allocated) = 0; + + // Does OnAlloc() need to be called? If false, metric collection overhead + // will be reduced since we will not do extra work per allocation. + virtual bool RecordAllocs() = 0; + + // OnAlloc is called when an allocation happens. + // type_info is promised to be static - its lifetime extends to + // match program's lifetime (It is given by typeid operator). + // Note: typeid(void) will be passed as allocated_type every time we + // intentionally want to avoid monitoring an allocation. (i.e. internal + // allocations for managing the arena) + virtual void OnAlloc(const std::type_info* allocated_type, + uint64 alloc_size) = 0; +}; + // This class provides the core Arena memory allocation library. Different // implementations only need to implement the public interface below. // Arena is not a template type as that would only be useful if all protos @@ -65,37 +98,23 @@ using LifecycleId = int64_t; // use #ifdef the select the best implementation based on hardware / OS. class PROTOBUF_EXPORT ArenaImpl { public: - struct Options { - size_t start_block_size; - size_t max_block_size; - char* initial_block; - size_t initial_block_size; - void* (*block_alloc)(size_t); - void (*block_dealloc)(void*, size_t); + static const size_t kDefaultStartBlockSize = 256; + static const size_t kDefaultMaxBlockSize = 8192; - template - explicit Options(const O& options) - : start_block_size(options.start_block_size), - max_block_size(options.max_block_size), - initial_block(options.initial_block), - initial_block_size(options.initial_block_size), - block_alloc(options.block_alloc), - block_dealloc(options.block_dealloc) {} - }; + ArenaImpl() { Init(false); } - template - explicit ArenaImpl(const O& options) : options_(options) { - if (options_.initial_block != NULL && options_.initial_block_size > 0) { - GOOGLE_CHECK_GE(options_.initial_block_size, sizeof(Block)) - << ": Initial block size too small for header."; - initial_block_ = reinterpret_cast(options_.initial_block); - } else { - initial_block_ = NULL; - } + ArenaImpl(char* mem, size_t size) { + GOOGLE_DCHECK_EQ(reinterpret_cast(mem) & 7, 0u); + Init(false); - Init(); + // Ignore initial block if it is too small. + if (mem != nullptr && size >= kBlockHeaderSize + kSerialArenaSize) { + SetInitialBlock(new (mem) Block(size, nullptr, true, true)); + } } + explicit ArenaImpl(const ArenaOptions& options); + // Destructor deletes all owned heap allocated objects, and destructs objects // that have non-trivial destructors, except for proto2 message objects whose // destructors can be skipped. Also, frees all blocks except the initial block @@ -134,6 +153,13 @@ class PROTOBUF_EXPORT ArenaImpl { // Add object pointer and cleanup function pointer to the list. void AddCleanup(void* elem, void (*cleanup)(void*)); + inline void RecordAlloc(const std::type_info* allocated_type, + size_t n) const { + if (PROTOBUF_PREDICT_FALSE(record_allocs())) { + options_->metrics_collector->OnAlloc(allocated_type, n); + } + } + private: friend class ArenaBenchmark; @@ -170,11 +196,6 @@ class PROTOBUF_EXPORT ArenaImpl { // Creates a new SerialArena inside Block* and returns it. static SerialArena* New(Block* b, void* owner, ArenaImpl* arena); - // Destroys this SerialArena, freeing all blocks with the given dealloc - // function, except any block equal to |initial_block|. - static uint64 Free(SerialArena* serial, Block* initial_block, - void (*block_dealloc)(void*, size_t)); - void CleanupList(); uint64 SpaceUsed() const; @@ -224,6 +245,7 @@ class PROTOBUF_EXPORT ArenaImpl { return ret; } + Block* head() const { return head_; } void* owner() const { return owner_; } SerialArena* next() const { return next_; } void set_next(SerialArena* next) { next_ = next; } @@ -254,25 +276,58 @@ class PROTOBUF_EXPORT ArenaImpl { // describes the common header for all blocks. class PROTOBUF_EXPORT Block { public: - Block(size_t size, Block* next); + Block(size_t size, Block* next, bool special, bool user_owned) + : next_and_bits_(reinterpret_cast(next) | (special ? 1 : 0) | + (user_owned ? 2 : 0)), + pos_(kBlockHeaderSize), + size_(size) { + GOOGLE_DCHECK_EQ(reinterpret_cast(next) & 3, 0u); + } char* Pointer(size_t n) { GOOGLE_DCHECK(n <= size_); return reinterpret_cast(this) + n; } - Block* next() const { return next_; } + // One of the blocks may be special. This is either a user-supplied + // initial block, or a block we created at startup to hold Options info. + // A special block is not deleted by Reset. + bool special() const { return (next_and_bits_ & 1) != 0; } + + // Whether or not this current block is owned by the user. + // Only special blocks can be user_owned. + bool user_owned() const { return (next_and_bits_ & 2) != 0; } + + Block* next() const { + const uintptr_t bottom_bits = 3; + return reinterpret_cast(next_and_bits_ & ~bottom_bits); + } + + void clear_next() { + next_and_bits_ &= 3; // Set next to nullptr, preserve bottom bits. + } + size_t pos() const { return pos_; } size_t size() const { return size_; } void set_pos(size_t pos) { pos_ = pos; } private: - Block* next_; // Next block for this thread. + // Holds pointer to next block for this thread + special/user_owned bits. + uintptr_t next_and_bits_; + size_t pos_; size_t size_; // data follows }; + struct Options { + size_t start_block_size; + size_t max_block_size; + void* (*block_alloc)(size_t); + void (*block_dealloc)(void*, size_t); + ArenaMetricsCollector* metrics_collector; + }; + struct ThreadCache { #if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL) // If we are using the ThreadLocalStorage class to store the ThreadCache, @@ -301,11 +356,30 @@ class PROTOBUF_EXPORT ArenaImpl { static ThreadCache& thread_cache() { return thread_cache_; } #endif - void Init(); + void Init(bool record_allocs); + void SetInitialBlock(Block* block); // Can be called right after Init() + + // Return true iff allocations should be recorded in a metrics collector. + inline bool record_allocs() const { return lifecycle_id_ & 1; } + + // Invoke fn(b) for every Block* b. + template + void PerBlock(Functor fn) { + // By omitting an Acquire barrier we ensure that any user code that doesn't + // properly synchronize Reset() or the destructor will throw a TSAN warning. + SerialArena* serial = threads_.load(std::memory_order_relaxed); + while (serial) { + // fn() may delete blocks and arenas, so fetch next pointers before fn(); + SerialArena* cur = serial; + serial = serial->next(); + for (Block* block = cur->head(); block != nullptr;) { + Block* b = block; + block = b->next(); + fn(b); + } + } + } - // Free all blocks and return the total space used which is the sums of sizes - // of the all the allocated blocks. - uint64 FreeBlocks(); // Delete or Destruct all objects owned by the arena. void CleanupList(); @@ -324,9 +398,6 @@ class PROTOBUF_EXPORT ArenaImpl { std::atomic hint_; // Fast thread-local block access std::atomic space_allocated_; // Total size of all allocated blocks. - Block* initial_block_; // If non-NULL, points to the block that came from - // user data. - Block* NewBlock(Block* last_block, size_t min_bytes); PROTOBUF_ALWAYS_INLINE bool GetSerialArenaFast(SerialArena** arena) { @@ -356,9 +427,12 @@ class PROTOBUF_EXPORT ArenaImpl { return false; } SerialArena* GetSerialArenaFallback(void* me); - LifecycleId lifecycle_id_; // Unique for each arena. Changes on Reset(). - Options options_; + // Unique for each arena. Changes on Reset(). + // Least-significant-bit is 1 iff allocations should be recorded. + LifecycleId lifecycle_id_; + + Options* options_ = nullptr; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ArenaImpl); // All protos have pointers back to the arena hence Arena must have @@ -373,6 +447,8 @@ class PROTOBUF_EXPORT ArenaImpl { (sizeof(Block) + 7) & static_cast(-8); static const size_t kSerialArenaSize = (sizeof(SerialArena) + 7) & static_cast(-8); + static const size_t kOptionsSize = + (sizeof(Options) + 7) & static_cast(-8); static_assert(kBlockHeaderSize % 8 == 0, "kBlockHeaderSize must be a multiple of 8."); static_assert(kSerialArenaSize % 8 == 0, diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 8919027a89..4695281197 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -272,28 +272,36 @@ TEST(ArenaTest, CreateWithMoveArguments) { } TEST(ArenaTest, InitialBlockTooSmall) { - // Construct a small (64 byte) initial block of memory to be used by the - // arena allocator; then, allocate an object which will not fit in the - // initial block. - std::vector arena_block(96); - ArenaOptions options; - options.initial_block = &arena_block[0]; - options.initial_block_size = arena_block.size(); - Arena arena(options); + // Construct a small blocks of memory to be used by the arena allocator; then, + // allocate an object which will not fit in the initial block. + for (int size = 0; size <= Arena::kBlockOverhead + 32; size++) { + std::vector arena_block(size); + ArenaOptions options; + options.initial_block = arena_block.data(); + options.initial_block_size = arena_block.size(); + + // Try sometimes with non-default block sizes so that we exercise paths + // with and without ArenaImpl::Options. + if ((size % 2) != 0) { + options.start_block_size += 8; + } - char* p = Arena::CreateArray(&arena, 96); - uintptr_t allocation = reinterpret_cast(p); + Arena arena(options); + + char* p = Arena::CreateArray(&arena, 96); + uintptr_t allocation = reinterpret_cast(p); - // Ensure that the arena allocator did not return memory pointing into the - // initial block of memory. - uintptr_t arena_start = reinterpret_cast(&arena_block[0]); - uintptr_t arena_end = arena_start + arena_block.size(); - EXPECT_FALSE(allocation >= arena_start && allocation < arena_end); + // Ensure that the arena allocator did not return memory pointing into the + // initial block of memory. + uintptr_t arena_start = reinterpret_cast(arena_block.data()); + uintptr_t arena_end = arena_start + arena_block.size(); + EXPECT_FALSE(allocation >= arena_start && allocation < arena_end); - // Write to the memory we allocated; this should (but is not guaranteed to) - // trigger a check for heap corruption if the object was allocated from the - // initially-provided block. - memset(p, '\0', 96); + // Write to the memory we allocated; this should (but is not guaranteed to) + // trigger a check for heap corruption if the object was allocated from the + // initially-provided block. + memset(p, '\0', 96); + } } TEST(ArenaTest, Parsing) { @@ -988,10 +996,7 @@ TEST(ArenaTest, ExtensionsOnArena) { TEST(ArenaTest, RepeatedFieldOnArena) { // Preallocate an initial arena block to avoid mallocs during hooked region. std::vector arena_block(1024 * 1024); - ArenaOptions options; - options.initial_block = &arena_block[0]; - options.initial_block_size = arena_block.size(); - Arena arena(options); + Arena arena(arena_block.data(), arena_block.size()); { internal::NoHeapChecker no_heap; @@ -1189,10 +1194,7 @@ TEST(ArenaTest, RepeatedFieldWithNonPODType) { uint64 Align8(uint64 n) { return (n + 7) & -8; } TEST(ArenaTest, SpaceAllocated_and_Used) { - ArenaOptions options; - options.start_block_size = 256; - options.max_block_size = 8192; - Arena arena_1(options); + Arena arena_1; EXPECT_EQ(0, arena_1.SpaceAllocated()); EXPECT_EQ(0, arena_1.SpaceUsed()); EXPECT_EQ(0, arena_1.Reset()); @@ -1204,6 +1206,9 @@ TEST(ArenaTest, SpaceAllocated_and_Used) { // Test with initial block. std::vector arena_block(1024); + ArenaOptions options; + options.start_block_size = 256; + options.max_block_size = 8192; options.initial_block = &arena_block[0]; options.initial_block_size = arena_block.size(); Arena arena_2(options); @@ -1214,19 +1219,25 @@ TEST(ArenaTest, SpaceAllocated_and_Used) { EXPECT_EQ(1024, arena_2.SpaceAllocated()); EXPECT_EQ(Align8(55), arena_2.SpaceUsed()); EXPECT_EQ(1024, arena_2.Reset()); +} - // Reset options to test doubling policy explicitly. - options.initial_block = NULL; - options.initial_block_size = 0; - Arena arena_3(options); - EXPECT_EQ(0, arena_3.SpaceUsed()); - Arena::CreateArray(&arena_3, 160); - EXPECT_EQ(256, arena_3.SpaceAllocated()); - EXPECT_EQ(Align8(160), arena_3.SpaceUsed()); - Arena::CreateArray(&arena_3, 70); - EXPECT_EQ(256 + 512, arena_3.SpaceAllocated()); - EXPECT_EQ(Align8(160) + Align8(70), arena_3.SpaceUsed()); - EXPECT_EQ(256 + 512, arena_3.Reset()); +TEST(ArenaTest, BlockSizeDoubling) { + Arena arena; + EXPECT_EQ(0, arena.SpaceUsed()); + EXPECT_EQ(0, arena.SpaceAllocated()); + + // Allocate something to get initial block size. + Arena::CreateArray(&arena, 1); + auto first_block_size = arena.SpaceAllocated(); + + // Keep allocating until space used increases. + while (arena.SpaceAllocated() == first_block_size) { + Arena::CreateArray(&arena, 1); + } + ASSERT_GT(arena.SpaceAllocated(), first_block_size); + auto second_block_size = (arena.SpaceAllocated() - first_block_size); + + EXPECT_EQ(second_block_size, 2*first_block_size); } TEST(ArenaTest, Alignment) { @@ -1304,81 +1315,93 @@ TEST(ArenaTest, AddCleanup) { } } -// A helper utility class to only contain static hook functions, some -// counters to be used to verify the counters have been called and a cookie -// value to be verified. -class ArenaHooksTestUtil { +namespace { +uint32 hooks_num_init = 0; +uint32 hooks_num_allocations = 0; +uint32 hooks_num_reset = 0; +uint32 hooks_num_destruct = 0; + +void ClearHookCounts() { + hooks_num_init = 0; + hooks_num_allocations = 0; + hooks_num_reset = 0; + hooks_num_destruct = 0; +} +} // namespace + +// A helper utility class that handles arena callbacks. +class ArenaOptionsTestFriend : public internal::ArenaMetricsCollector { public: - static void* on_init(Arena* arena) { - ++num_init; - int* cookie = new int(kCookieValue); - return static_cast(cookie); + static internal::ArenaMetricsCollector* NewWithAllocs() { + return new ArenaOptionsTestFriend(true); } - static void on_allocation(const std::type_info* /*unused*/, uint64 alloc_size, - void* cookie) { - ++num_allocations; - int cookie_value = *static_cast(cookie); - EXPECT_EQ(kCookieValue, cookie_value); + static internal::ArenaMetricsCollector* NewWithoutAllocs() { + return new ArenaOptionsTestFriend(false); } - static void on_reset(Arena* arena, void* cookie, uint64 space_used) { - ++num_reset; - int cookie_value = *static_cast(cookie); - EXPECT_EQ(kCookieValue, cookie_value); + static void Enable(ArenaOptions* options) { + ClearHookCounts(); + options->make_metrics_collector = &ArenaOptionsTestFriend::NewWithAllocs; } - static void on_destruction(Arena* arena, void* cookie, uint64 space_used) { - ++num_destruct; - int cookie_value = *static_cast(cookie); - EXPECT_EQ(kCookieValue, cookie_value); - delete static_cast(cookie); + static void EnableWithoutAllocs(ArenaOptions* options) { + ClearHookCounts(); + options->make_metrics_collector = &ArenaOptionsTestFriend::NewWithoutAllocs; } - static const int kCookieValue = 999; - static uint32 num_init; - static uint32 num_allocations; - static uint32 num_reset; - static uint32 num_destruct; -}; -uint32 ArenaHooksTestUtil::num_init = 0; -uint32 ArenaHooksTestUtil::num_allocations = 0; -uint32 ArenaHooksTestUtil::num_reset = 0; -uint32 ArenaHooksTestUtil::num_destruct = 0; -const int ArenaHooksTestUtil::kCookieValue; - -class ArenaOptionsTestFriend { - public: - static void Set(ArenaOptions* options) { - options->on_arena_init = ArenaHooksTestUtil::on_init; - options->on_arena_allocation = ArenaHooksTestUtil::on_allocation; - options->on_arena_reset = ArenaHooksTestUtil::on_reset; - options->on_arena_destruction = ArenaHooksTestUtil::on_destruction; + explicit ArenaOptionsTestFriend(bool record_allocs) + : record_allocs_(record_allocs) { + ++hooks_num_init; } + void OnDestroy(uint64 space_allocated) override { + ++hooks_num_destruct; + delete this; + } + void OnReset(uint64 space_allocated) override { ++hooks_num_reset; } + bool RecordAllocs() override { return record_allocs_; } + void OnAlloc(const std::type_info* allocated_type, + uint64 alloc_size) override { + ++hooks_num_allocations; + } + + private: + bool record_allocs_; }; -// Test the hooks are correctly called and that the cookie is passed. +// Test the hooks are correctly called. TEST(ArenaTest, ArenaHooksSanity) { ArenaOptions options; - ArenaOptionsTestFriend::Set(&options); + ArenaOptionsTestFriend::Enable(&options); // Scope for defining the arena { Arena arena(options); - EXPECT_EQ(1, ArenaHooksTestUtil::num_init); - EXPECT_EQ(0, ArenaHooksTestUtil::num_allocations); + EXPECT_EQ(1, hooks_num_init); + EXPECT_EQ(0, hooks_num_allocations); Arena::Create(&arena); if (std::is_trivially_destructible::value) { - EXPECT_EQ(1, ArenaHooksTestUtil::num_allocations); + EXPECT_EQ(1, hooks_num_allocations); } else { - EXPECT_EQ(2, ArenaHooksTestUtil::num_allocations); + EXPECT_EQ(2, hooks_num_allocations); } arena.Reset(); arena.Reset(); - EXPECT_EQ(2, ArenaHooksTestUtil::num_reset); + EXPECT_EQ(2, hooks_num_reset); } - EXPECT_EQ(3, ArenaHooksTestUtil::num_reset); - EXPECT_EQ(1, ArenaHooksTestUtil::num_destruct); + EXPECT_EQ(2, hooks_num_reset); + EXPECT_EQ(1, hooks_num_destruct); +} + +// Test that allocation hooks are not called when we don't need them. +TEST(ArenaTest, ArenaHooksWhenAllocationsNotNeeded) { + ArenaOptions options; + ArenaOptionsTestFriend::EnableWithoutAllocs(&options); + + Arena arena(options); + EXPECT_EQ(0, hooks_num_allocations); + Arena::Create(&arena); + EXPECT_EQ(0, hooks_num_allocations); } diff --git a/src/google/protobuf/arenastring.cc b/src/google/protobuf/arenastring.cc new file mode 100644 index 0000000000..b5f48c53a1 --- /dev/null +++ b/src/google/protobuf/arenastring.cc @@ -0,0 +1,254 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// clang-format off +#include +// clang-format on + +namespace google { +namespace protobuf { +namespace internal { + +const std::string& LazyString::Init() const { + static WrappedMutex mu{GOOGLE_PROTOBUF_LINKER_INITIALIZED}; + mu.Lock(); + const std::string* res = inited_.load(std::memory_order_acquire); + if (res == nullptr) { + auto init_value = init_value_; + res = ::new (static_cast(string_buf_)) + std::string(init_value.ptr, init_value.size); + inited_.store(res, std::memory_order_release); + } + mu.Unlock(); + return *res; +} + + +void ArenaStringPtr::Set(const std::string* default_value, + ConstStringParam value, ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + tagged_ptr_.Set(Arena::Create(arena, value)); + } else { + UnsafeMutablePointer()->assign(value.data(), value.length()); + } +} + +void ArenaStringPtr::Set(const std::string* default_value, std::string&& value, + ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + if (arena == nullptr) { + tagged_ptr_.Set(new std::string(std::move(value))); + } else { + tagged_ptr_.Set(Arena::Create(arena, std::move(value))); + } + } else if (IsDonatedString()) { + std::string* current = tagged_ptr_.Get(); + auto* s = new (current) std::string(std::move(value)); + arena->OwnDestructor(s); + tagged_ptr_.Set(s); + } else /* !IsDonatedString() */ { + *UnsafeMutablePointer() = std::move(value); + } +} + +void ArenaStringPtr::Set(EmptyDefault, ConstStringParam value, + ::google::protobuf::Arena* arena) { + Set(&GetEmptyStringAlreadyInited(), value, arena); +} + +void ArenaStringPtr::Set(EmptyDefault, std::string&& value, + ::google::protobuf::Arena* arena) { + Set(&GetEmptyStringAlreadyInited(), std::move(value), arena); +} + +void ArenaStringPtr::Set(NonEmptyDefault, ConstStringParam value, + ::google::protobuf::Arena* arena) { + Set(nullptr, value, arena); +} + +void ArenaStringPtr::Set(NonEmptyDefault, std::string&& value, + ::google::protobuf::Arena* arena) { + Set(nullptr, std::move(value), arena); +} + +std::string* ArenaStringPtr::Mutable(EmptyDefault, ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(&GetEmptyStringAlreadyInited())) { + return UnsafeMutablePointer(); + } else { + return MutableSlow(arena); + } +} + +std::string* ArenaStringPtr::Mutable(const LazyString& default_value, + ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(nullptr)) { + return UnsafeMutablePointer(); + } else { + return MutableSlow(arena, default_value); + } +} + +std::string* ArenaStringPtr::MutableNoCopy(const std::string* default_value, + ::google::protobuf::Arena* arena) { + if (!IsDonatedString() && !IsDefault(default_value)) { + return UnsafeMutablePointer(); + } else { + GOOGLE_DCHECK(IsDefault(default_value)); + // Allocate empty. The contents are not relevant. + std::string* new_string = Arena::Create(arena); + tagged_ptr_.Set(new_string); + return new_string; + } +} + +template +std::string* ArenaStringPtr::MutableSlow(::google::protobuf::Arena* arena, + const Lazy&... lazy_default) { + const std::string* const default_value = + sizeof...(Lazy) == 0 ? &GetEmptyStringAlreadyInited() : nullptr; + GOOGLE_DCHECK(IsDefault(default_value)); + std::string* new_string = + Arena::Create(arena, lazy_default.get()...); + tagged_ptr_.Set(new_string); + return new_string; +} + +std::string* ArenaStringPtr::Release(const std::string* default_value, + ::google::protobuf::Arena* arena) { + if (IsDefault(default_value)) { + return nullptr; + } else { + return ReleaseNonDefault(default_value, arena); + } +} + +std::string* ArenaStringPtr::ReleaseNonDefault(const std::string* default_value, + ::google::protobuf::Arena* arena) { + GOOGLE_DCHECK(!IsDefault(default_value)); + + if (!IsDonatedString()) { + std::string* released; + if (arena != nullptr) { + released = new std::string; + released->swap(*UnsafeMutablePointer()); + } else { + released = UnsafeMutablePointer(); + } + tagged_ptr_.Set(const_cast(default_value)); + return released; + } else /* IsDonatedString() */ { + GOOGLE_DCHECK(arena != nullptr); + std::string* released = new std::string(Get()); + tagged_ptr_.Set(const_cast(default_value)); + return released; + } +} + +void ArenaStringPtr::SetAllocated(const std::string* default_value, + std::string* value, ::google::protobuf::Arena* arena) { + // Release what we have first. + if (arena == nullptr && !IsDefault(default_value)) { + delete UnsafeMutablePointer(); + } + if (value == nullptr) { + tagged_ptr_.Set(const_cast(default_value)); + } else { +#ifdef NDEBUG + tagged_ptr_.Set(value); + if (arena != nullptr) { + arena->Own(value); + } +#else + // On debug builds, copy the string so the address differs. delete will + // fail if value was a stack-allocated temporary/etc., which would have + // failed when arena ran its cleanup list. + std::string* new_value = Arena::Create(arena, *value); + delete value; + tagged_ptr_.Set(new_value); +#endif + } +} + +void ArenaStringPtr::Destroy(const std::string* default_value, + ::google::protobuf::Arena* arena) { + if (arena == nullptr) { + GOOGLE_DCHECK(!IsDonatedString()); + if (!IsDefault(default_value)) { + delete UnsafeMutablePointer(); + } + } +} + +void ArenaStringPtr::Destroy(EmptyDefault, ::google::protobuf::Arena* arena) { + Destroy(&GetEmptyStringAlreadyInited(), arena); +} + +void ArenaStringPtr::Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena) { + Destroy(nullptr, arena); +} + +void ArenaStringPtr::ClearToEmpty() { + if (IsDefault(&GetEmptyStringAlreadyInited())) { + // Already set to default -- do nothing. + } else { + // Unconditionally mask away the tag. + // + // UpdateDonatedString uses assign when capacity is larger than the new + // value, which is trivially true in the donated string case. + // const_cast(PtrValue())->clear(); + tagged_ptr_.Get()->clear(); + } +} + +void ArenaStringPtr::ClearToDefault(const LazyString& default_value, + ::google::protobuf::Arena* arena) { + (void)arena; + if (IsDefault(nullptr)) { + // Already set to default -- do nothing. + } else if (!IsDonatedString()) { + UnsafeMutablePointer()->assign(default_value.get()); + } +} + + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index b87be8e39b..e23459f7c2 100644 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -37,7 +37,6 @@ #include #include -#include #include #include @@ -48,23 +47,57 @@ #endif -// This is the implementation of arena string fields written for the open-source -// release. The ArenaStringPtr struct below is an internal implementation class -// and *should not be used* by user code. It is used to collect string -// operations together into one place and abstract away the underlying -// string-field pointer representation, so that (for example) an alternate -// implementation that knew more about ::std::string's internals could integrate -// more closely with the arena allocator. - namespace google { namespace protobuf { namespace internal { +// Lazy string instance to support string fields with non-empty default. +// These are initialized on the first call to .get(). +class PROTOBUF_EXPORT LazyString { + public: + // We explicitly make LazyString an aggregate so that MSVC can do constant + // initialization on it without marking it `constexpr`. + // We do not want to use `constexpr` because it makes it harder to have extern + // storage for it and causes library bloat. + struct InitValue { + const char* ptr; + size_t size; + }; + // We keep a union of the initialization value and the std::string to save on + // space. We don't need the string array after Init() is done. + union { + mutable InitValue init_value_; + alignas(std::string) mutable char string_buf_[sizeof(std::string)]; + }; + mutable std::atomic inited_; + + const std::string& get() const { + // This check generates less code than a call-once invocation. + auto* res = inited_.load(std::memory_order_acquire); + if (PROTOBUF_PREDICT_FALSE(res == nullptr)) return Init(); + return *res; + } + + private: + // Initialize the string in `string_buf_`, update `inited_` and return it. + // We return it here to avoid having to read it again in the inlined code. + const std::string& Init() const; +}; + template class TaggedPtr { public: + void SetTagged(T* p) { + Set(p); + ptr_ |= 1; + } void Set(T* p) { ptr_ = reinterpret_cast(p); } - T* Get() const { return reinterpret_cast(ptr_); } + T* Get() const { return reinterpret_cast(ptr_ & -2); } + bool IsTagged() const { return ptr_ & 1; } + + // Returned value is only safe to dereference if IsTagged() == false. + // It is safe to compare. + T* UnsafeGet() const { return reinterpret_cast(ptr_); } bool IsNull() { return ptr_ == 0; } @@ -72,237 +105,266 @@ class TaggedPtr { uintptr_t ptr_; }; -struct PROTOBUF_EXPORT ArenaStringPtr { - inline void Set(const ::std::string* default_value, - const ::std::string& value, Arena* arena) { - if (ptr_ == default_value) { - CreateInstance(arena, &value); - } else { - *ptr_ = value; - } - } +static_assert(std::is_trivial>::value, + "TaggedPtr must be trivial"); - inline void SetLite(const ::std::string* default_value, - const ::std::string& value, Arena* arena) { - Set(default_value, value, arena); - } +// This class encapsulates a pointer to a std::string with or without a donated +// buffer, tagged by bottom bit. It is a high-level wrapper that almost directly +// corresponds to the interface required by string fields in generated +// code. It replaces the old std::string* pointer in such cases. +// +// The object has different but similar code paths for when the default value is +// the empty string and when it is a non-empty string. +// The empty string is handled different throughout the library and there is a +// single global instance of it we can share. +// +// For fields with an empty string default value, there are three distinct +// states: +// +// - Pointer set to 'String' tag (LSB is 0), equal to +// &GetEmptyStringAlreadyInited(): field is set to its default value. Points +// to a true std::string*, but we do not own that std::string* (it's a +// globally shared instance). +// +// - Pointer set to 'String' tag (LSB is 0), but not equal to the global empty +// string: field points to a true std::string* instance that we own. This +// instance is either on the heap or on the arena (i.e. registered on +// free()/destructor-call list) as appropriate. +// +// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string +// instance with a buffer on the arena (arena != NULL, always, in this case). +// +// For fields with a non-empty string default value, there are three distinct +// states: +// +// - Pointer set to 'String' tag (LSB is 0), equal to `nullptr`: +// Field is in "default" mode and does not point to any actual instance. +// Methods that might need to create an instance of the object will pass a +// `const LazyString&` for it. +// +// - Pointer set to 'String' tag (LSB is 0), but not equal to `nullptr`: +// field points to a true std::string* instance that we own. This instance is +// either on the heap or on the arena (i.e. registered on +// free()/destructor-call list) as appropriate. +// +// - Pointer set to 'DonatedString' tag (LSB is 1): points to a std::string +// instance with a buffer on the arena (arena != NULL, always, in this case). +// +// Generated code and reflection code both ensure that ptr_ is never null for +// fields with an empty default. +// Because ArenaStringPtr is used in oneof unions, its constructor is a NOP and +// so the field is always manually initialized via method calls. +// +// Side-note: why pass information about the default on every API call? Because +// we don't want to hold it in a member variable, or else this would go into +// every proto message instance. This would be a huge waste of space, since the +// default instance pointer is typically a global (static class field). We want +// the generated code to be as efficient as possible, and if we take +// the default value information as a parameter that's in practice taken from a +// static class field, and compare ptr_ to the default value, we end up with a +// single "cmp %reg, GLOBAL" in the resulting machine code. (Note that this also +// requires the String tag to be 0 so we can avoid the mask before comparing.) +struct PROTOBUF_EXPORT ArenaStringPtr { + // No default constructor or destructor -- we have to be POD because we go + // into a union when used in a oneof. Message code calls UnsafeReset() to zero + // the pointer when necessary instead. + + // Some methods below are overloaded on a `default_value` and on tags. + // The tagged overloads help reduce code size in the callers in generated + // code, while the `default_value` overloads are useful from reflection. + // By-value empty struct arguments are elided in the ABI. + struct EmptyDefault {}; + struct NonEmptyDefault {}; + + void Set(const std::string* default_value, ConstStringParam value, + ::google::protobuf::Arena* arena); + void Set(const std::string* default_value, std::string&& value, + ::google::protobuf::Arena* arena); + void Set(EmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); + void Set(EmptyDefault, std::string&& value, ::google::protobuf::Arena* arena); + void Set(NonEmptyDefault, ConstStringParam value, ::google::protobuf::Arena* arena); + void Set(NonEmptyDefault, std::string&& value, ::google::protobuf::Arena* arena); // Basic accessors. - inline const ::std::string& Get() const { return *ptr_; } - - inline ::std::string* Mutable(const ::std::string* default_value, - Arena* arena) { - if (ptr_ == default_value) { - CreateInstance(arena, default_value); - } - return ptr_; + const std::string& Get() const PROTOBUF_ALWAYS_INLINE { + // Unconditionally mask away the tag. + return *tagged_ptr_.Get(); } - - // Release returns a ::std::string* instance that is heap-allocated and is not - // Own()'d by any arena. If the field was not set, it returns NULL. The caller - // retains ownership. Clears this field back to NULL state. Used to implement - // release_() methods on generated classes. - inline ::std::string* Release(const ::std::string* default_value, - Arena* arena) { - if (ptr_ == default_value) { - return NULL; - } - return ReleaseNonDefault(default_value, arena); + const std::string* GetPointer() const PROTOBUF_ALWAYS_INLINE { + // Unconditionally mask away the tag. + return tagged_ptr_.Get(); } - // Similar to Release, but ptr_ cannot be the default_value. - inline ::std::string* ReleaseNonDefault(const ::std::string* default_value, - Arena* arena) { - GOOGLE_DCHECK(!IsDefault(default_value)); - ::std::string* released = NULL; - if (arena != NULL) { - // ptr_ is owned by the arena. - released = new ::std::string; - released->swap(*ptr_); - } else { - released = ptr_; - } - ptr_ = const_cast< ::std::string*>(default_value); - return released; - } - - // UnsafeArenaRelease returns a ::std::string*, but it may be arena-owned - // (i.e. have its destructor already registered) if arena != NULL. If the - // field was not set, this returns NULL. This method clears this field back to - // NULL state. Used to implement unsafe_arena_release_() methods on - // generated classes. - inline ::std::string* UnsafeArenaRelease(const ::std::string* default_value, - Arena* /* arena */) { - if (ptr_ == default_value) { - return NULL; - } - ::std::string* released = ptr_; - ptr_ = const_cast< ::std::string*>(default_value); - return released; - } - - // Takes a string that is heap-allocated, and takes ownership. The string's - // destructor is registered with the arena. Used to implement + // For fields with an empty default value. + std::string* Mutable(EmptyDefault, ::google::protobuf::Arena* arena); + // For fields with a non-empty default value. + std::string* Mutable(const LazyString& default_value, ::google::protobuf::Arena* arena); + + // Release returns a std::string* instance that is heap-allocated and is not + // Own()'d by any arena. If the field is not set, this returns NULL. The + // caller retains ownership. Clears this field back to NULL state. Used to + // implement release_() methods on generated classes. + std::string* Release(const std::string* default_value, + ::google::protobuf::Arena* arena); + std::string* ReleaseNonDefault(const std::string* default_value, + ::google::protobuf::Arena* arena); + + // Takes a std::string that is heap-allocated, and takes ownership. The + // std::string's destructor is registered with the arena. Used to implement // set_allocated_ in generated classes. - inline void SetAllocated(const ::std::string* default_value, - ::std::string* value, Arena* arena) { - if (arena == NULL && ptr_ != default_value) { - Destroy(default_value, arena); - } - if (value != NULL) { - ptr_ = value; - if (arena != NULL) { - arena->Own(value); - } - } else { - ptr_ = const_cast< ::std::string*>(default_value); - } - } - - // Takes a string that has lifetime equal to the arena's lifetime. The arena - // must be non-null. It is safe only to pass this method a value returned by - // UnsafeArenaRelease() on another field of a message in the same arena. Used - // to implement unsafe_arena_set_allocated_ in generated classes. - inline void UnsafeArenaSetAllocated(const ::std::string* default_value, - ::std::string* value, - Arena* /* arena */) { - if (value != NULL) { - ptr_ = value; - } else { - ptr_ = const_cast< ::std::string*>(default_value); - } - } + void SetAllocated(const std::string* default_value, std::string* value, + ::google::protobuf::Arena* arena); // Swaps internal pointers. Arena-safety semantics: this is guarded by the // logic in Swap()/UnsafeArenaSwap() at the message level, so this method is // 'unsafe' if called directly. - PROTOBUF_ALWAYS_INLINE void Swap(ArenaStringPtr* other) { - std::swap(ptr_, other->ptr_); - } - PROTOBUF_ALWAYS_INLINE void Swap(ArenaStringPtr* other, - const ::std::string* default_value, - Arena* arena) { -#ifndef NDEBUG - // For debug builds, we swap the contents of the string, rather than the - // string instances themselves. This invalidates previously taken const - // references that are (per our documentation) invalidated by calling Swap() - // on the message. - // - // If both strings are the default_value, swapping is uninteresting. - // Otherwise, we use ArenaStringPtr::Mutable() to access the string, to - // ensure that we do not try to mutate default_value itself. - if (IsDefault(default_value) && other->IsDefault(default_value)) { - return; - } - - ::std::string* this_ptr = Mutable(default_value, arena); - ::std::string* other_ptr = other->Mutable(default_value, arena); - - this_ptr->swap(*other_ptr); -#else - std::swap(ptr_, other->ptr_); - (void)default_value; - (void)arena; -#endif - } + inline void Swap(ArenaStringPtr* other, const std::string* default_value, + Arena* arena) PROTOBUF_ALWAYS_INLINE; // Frees storage (if not on an arena). - inline void Destroy(const ::std::string* default_value, Arena* arena) { - if (arena == NULL && ptr_ != default_value) { - delete ptr_; - } - } + void Destroy(const std::string* default_value, ::google::protobuf::Arena* arena); + void Destroy(EmptyDefault, ::google::protobuf::Arena* arena); + void Destroy(NonEmptyDefault, ::google::protobuf::Arena* arena); - // Clears content, but keeps allocated string if arena != NULL, to avoid the - // overhead of heap operations. After this returns, the content (as seen by - // the user) will always be the empty string. Assumes that |default_value| - // is an empty string. - inline void ClearToEmpty(const ::std::string* default_value, - Arena* /* arena */) { - if (ptr_ == default_value) { - // Already set to default (which is empty) -- do nothing. - } else { - ptr_->clear(); - } - } + // Clears content, but keeps allocated std::string, to avoid the overhead of + // heap operations. After this returns, the content (as seen by the user) will + // always be the empty std::string. Assumes that |default_value| is an empty + // std::string. + void ClearToEmpty(); - // Clears content, assuming that the current value is not the empty string - // default. - inline void ClearNonDefaultToEmpty() { ptr_->clear(); } - - // Clears content, but keeps allocated string if arena != NULL, to avoid the - // overhead of heap operations. After this returns, the content (as seen by - // the user) will always be equal to |default_value|. - inline void ClearToDefault(const ::std::string* default_value, - Arena* /* arena */) { - if (ptr_ == default_value) { - // Already set to default -- do nothing. - } else { - // Have another allocated string -- rather than throwing this away and - // resetting ptr_ to the canonical default string instance, we just reuse - // this instance. - *ptr_ = *default_value; - } - } + // Clears content, assuming that the current value is not the empty + // string default. + void ClearNonDefaultToEmpty(); + + // Clears content, but keeps allocated std::string if arena != NULL, to avoid + // the overhead of heap operations. After this returns, the content (as seen + // by the user) will always be equal to |default_value|. + void ClearToDefault(const LazyString& default_value, ::google::protobuf::Arena* arena); // Called from generated code / reflection runtime only. Resets value to point - // to a default string pointer, with the semantics that this ArenaStringPtr - // does not own the pointed-to memory. Disregards initial value of ptr_ (so - // this is the *ONLY* safe method to call after construction or when - // reinitializing after becoming the active field in a oneof union). - inline void UnsafeSetDefault(const ::std::string* default_value) { - // Casting away 'const' is safe here: accessors ensure that ptr_ is only - // returned as a const if it is equal to default_value. - ptr_ = const_cast< ::std::string*>(default_value); - } + // to a default string pointer, with the semantics that this + // ArenaStringPtr does not own the pointed-to memory. Disregards initial value + // of ptr_ (so this is the *ONLY* safe method to call after construction or + // when reinitializing after becoming the active field in a oneof union). + inline void UnsafeSetDefault(const std::string* default_value); + + // Returns a mutable pointer, but doesn't initialize the string to the + // default value. + std::string* MutableNoArenaNoDefault(const std::string* default_value); + + // Get a mutable pointer with unspecified contents. + // Similar to `MutableNoArenaNoDefault`, but also handles the arena case. + // If the value was donated, the contents are discarded. + std::string* MutableNoCopy(const std::string* default_value, + ::google::protobuf::Arena* arena); // Destroy the string. Assumes `arena == nullptr`. - inline void DestroyNoArena(const ::std::string* default_value) { - if (ptr_ != default_value) { - delete ptr_; - } - } - - // Internal accessor used only at parse time to provide direct access to the - // raw pointer from the shared parse routine (in the non-arenas case). The - // parse routine does the string allocation in order to save code size in the - // generated parsing code. - inline ::std::string** UnsafeRawStringPointer() { return &ptr_; } - - inline bool IsDefault(const ::std::string* default_value) const { - return ptr_ == default_value; - } + void DestroyNoArena(const std::string* default_value); - // Internal accessors!!!! - void UnsafeSetTaggedPointer(TaggedPtr< ::std::string> value) { - ptr_ = value.Get(); + // Internal setter used only at parse time to directly set a donated string + // value. + void UnsafeSetTaggedPointer(TaggedPtr value) { + tagged_ptr_ = value; } // Generated code only! An optimization, in certain cases the generated - // code is certain we can obtain a string with no default checks and + // code is certain we can obtain a std::string with no default checks and // tag tests. - ::std::string* UnsafeMutablePointer() { return ptr_; } + std::string* UnsafeMutablePointer() PROTOBUF_RETURNS_NONNULL; + + inline bool IsDefault(const std::string* default_value) const { + // Relies on the fact that kPtrTagString == 0, so if IsString(), ptr_ is the + // actual std::string pointer (and if !IsString(), ptr_ will never be equal + // to any aligned |default_value| pointer). The key is that we want to avoid + // masking in the fastpath const-pointer Get() case for non-arena code. + return tagged_ptr_.UnsafeGet() == default_value; + } private: - ::std::string* ptr_; + TaggedPtr tagged_ptr_; + + bool IsDonatedString() const { return false; } + + // Slow paths. - PROTOBUF_NOINLINE - void CreateInstance(Arena* arena, const ::std::string* initial_value) { - GOOGLE_DCHECK(initial_value != NULL); - // uses "new ::std::string" when arena is nullptr - ptr_ = Arena::Create< ::std::string>(arena, *initial_value); + // MutableSlow requires that !IsString() || IsDefault + // Variadic to support 0 args for EmptyDefault and 1 arg for LazyString. + template + std::string* MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default); + +}; + +inline void ArenaStringPtr::UnsafeSetDefault(const std::string* value) { + tagged_ptr_.Set(const_cast(value)); +} + +inline void ArenaStringPtr::Swap(ArenaStringPtr* other, + const std::string* default_value, + Arena* arena) { +#ifndef NDEBUG + // For debug builds, we swap the contents of the string, rather than the + // std::string instances themselves. This invalidates previously taken const + // references that are (per our documentation) invalidated by calling Swap() + // on the message. + // + // If both strings are the default_value, swapping is uninteresting. + // Otherwise, we use ArenaStringPtr::Mutable() to access the std::string, to + // ensure that we do not try to mutate default_value itself. + if (IsDefault(default_value) && other->IsDefault(default_value)) { + return; } - PROTOBUF_NOINLINE - void CreateInstanceNoArena(const ::std::string* initial_value) { - GOOGLE_DCHECK(initial_value != NULL); - ptr_ = new ::std::string(*initial_value); + + if (default_value == nullptr) { + // If we have non-empty default, then `default_value` is null and we can't + // call Mutable the same way. Just do the regular swap. + std::swap(tagged_ptr_, other->tagged_ptr_); + } else { + std::string* this_ptr = Mutable(EmptyDefault{}, arena); + std::string* other_ptr = other->Mutable(EmptyDefault{}, arena); + + this_ptr->swap(*other_ptr); } -}; +#else + std::swap(tagged_ptr_, other->tagged_ptr_); +#endif +} + +inline void ArenaStringPtr::ClearNonDefaultToEmpty() { + // Unconditionally mask away the tag. + tagged_ptr_.Get()->clear(); +} + +inline std::string* ArenaStringPtr::MutableNoArenaNoDefault( + const std::string* default_value) { + // VERY IMPORTANT for performance and code size: this will reduce to a member + // variable load, a pointer check (against |default_value|, in practice a + // static global) and a branch to the slowpath (which calls operator new and + // the ctor). DO NOT add any tagged-pointer operations here. + if (IsDefault(default_value)) { + std::string* new_string = new std::string(); + tagged_ptr_.Set(new_string); + return new_string; + } else { + return UnsafeMutablePointer(); + } +} + +inline void ArenaStringPtr::DestroyNoArena(const std::string* default_value) { + if (!IsDefault(default_value)) { + delete UnsafeMutablePointer(); + } +} + +inline std::string* ArenaStringPtr::UnsafeMutablePointer() { + GOOGLE_DCHECK(!tagged_ptr_.IsTagged()); + GOOGLE_DCHECK(tagged_ptr_.UnsafeGet() != nullptr); + return tagged_ptr_.UnsafeGet(); +} + } // namespace internal } // namespace protobuf } // namespace google - #include #endif // GOOGLE_PROTOBUF_ARENASTRING_H__ diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc index c5da4476b4..07e7c650dd 100644 --- a/src/google/protobuf/arenastring_unittest.cc +++ b/src/google/protobuf/arenastring_unittest.cc @@ -28,8 +28,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Based on mvels@'s frankenstring. - #include #include @@ -42,6 +40,7 @@ #include #include #include +#include #include #include @@ -53,82 +52,119 @@ using internal::ArenaStringPtr; static std::string WrapString(const char* value) { return value; } +using EmptyDefault = ArenaStringPtr::EmptyDefault; + +const internal::LazyString nonempty_default{{{"default", 7}}, {nullptr}}; + // Test ArenaStringPtr with arena == NULL. TEST(ArenaStringPtrTest, ArenaStringPtrOnHeap) { ArenaStringPtr field; - std::string default_value = "default"; - field.UnsafeSetDefault(&default_value); - EXPECT_EQ(std::string("default"), field.Get()); - field.Set(&default_value, WrapString("Test short"), NULL); + const std::string* empty_default = &internal::GetEmptyString(); + field.UnsafeSetDefault(empty_default); + EXPECT_EQ(std::string(""), field.Get()); + field.Set(empty_default, WrapString("Test short"), NULL); EXPECT_EQ(std::string("Test short"), field.Get()); - field.Set(&default_value, WrapString("Test long long long long value"), NULL); + field.Set(empty_default, WrapString("Test long long long long value"), NULL); EXPECT_EQ(std::string("Test long long long long value"), field.Get()); - field.Set(&default_value, std::string(""), NULL); - field.Destroy(&default_value, NULL); + field.Set(empty_default, std::string(""), NULL); + field.Destroy(empty_default, NULL); ArenaStringPtr field2; - field2.UnsafeSetDefault(&default_value); - std::string* mut = field2.Mutable(&default_value, NULL); - EXPECT_EQ(mut, field2.Mutable(&default_value, NULL)); + field2.UnsafeSetDefault(empty_default); + std::string* mut = field2.Mutable(EmptyDefault{}, NULL); + EXPECT_EQ(mut, field2.Mutable(EmptyDefault{}, NULL)); EXPECT_EQ(mut, &field2.Get()); - EXPECT_NE(&default_value, mut); - EXPECT_EQ(std::string("default"), *mut); + EXPECT_NE(empty_default, mut); + EXPECT_EQ(std::string(""), *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ(std::string("Test long long long long value"), field2.Get()); - field2.Destroy(&default_value, NULL); + field2.Destroy(empty_default, NULL); + + ArenaStringPtr field3; + field3.UnsafeSetDefault(nullptr); + mut = field3.Mutable(nonempty_default, NULL); + EXPECT_EQ(mut, field3.Mutable(nonempty_default, NULL)); + EXPECT_EQ(mut, &field3.Get()); + EXPECT_NE(nullptr, mut); + EXPECT_EQ(std::string("default"), *mut); + *mut = "Test long long long long value"; // ensure string allocates storage + EXPECT_EQ(std::string("Test long long long long value"), field3.Get()); + field3.Destroy(nullptr, NULL); } TEST(ArenaStringPtrTest, ArenaStringPtrOnArena) { Arena arena; ArenaStringPtr field; - std::string default_value = "default"; - field.UnsafeSetDefault(&default_value); - EXPECT_EQ(std::string("default"), field.Get()); - field.Set(&default_value, WrapString("Test short"), &arena); + const std::string* empty_default = &internal::GetEmptyString(); + field.UnsafeSetDefault(empty_default); + EXPECT_EQ(std::string(""), field.Get()); + field.Set(empty_default, WrapString("Test short"), &arena); EXPECT_EQ(std::string("Test short"), field.Get()); - field.Set(&default_value, WrapString("Test long long long long value"), + field.Set(empty_default, WrapString("Test long long long long value"), &arena); EXPECT_EQ(std::string("Test long long long long value"), field.Get()); - field.Set(&default_value, std::string(""), &arena); - field.Destroy(&default_value, &arena); + field.Set(empty_default, std::string(""), &arena); + field.Destroy(empty_default, &arena); ArenaStringPtr field2; - field2.UnsafeSetDefault(&default_value); - std::string* mut = field2.Mutable(&default_value, &arena); - EXPECT_EQ(mut, field2.Mutable(&default_value, &arena)); + field2.UnsafeSetDefault(empty_default); + std::string* mut = field2.Mutable(EmptyDefault{}, &arena); + EXPECT_EQ(mut, field2.Mutable(EmptyDefault{}, &arena)); EXPECT_EQ(mut, &field2.Get()); - EXPECT_NE(&default_value, mut); - EXPECT_EQ(std::string("default"), *mut); + EXPECT_NE(empty_default, mut); + EXPECT_EQ(std::string(""), *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ(std::string("Test long long long long value"), field2.Get()); - field2.Destroy(&default_value, &arena); + field2.Destroy(empty_default, &arena); + + ArenaStringPtr field3; + field3.UnsafeSetDefault(nullptr); + mut = field3.Mutable(nonempty_default, &arena); + EXPECT_EQ(mut, field3.Mutable(nonempty_default, &arena)); + EXPECT_EQ(mut, &field3.Get()); + EXPECT_NE(nullptr, mut); + EXPECT_EQ(std::string("default"), *mut); + *mut = "Test long long long long value"; // ensure string allocates storage + EXPECT_EQ(std::string("Test long long long long value"), field3.Get()); + field3.Destroy(nullptr, &arena); } TEST(ArenaStringPtrTest, ArenaStringPtrOnArenaNoSSO) { Arena arena; ArenaStringPtr field; - std::string default_value = "default"; - field.UnsafeSetDefault(&default_value); - EXPECT_EQ(std::string("default"), field.Get()); + const std::string* empty_default = &internal::GetEmptyString(); + field.UnsafeSetDefault(empty_default); + EXPECT_EQ(std::string(""), field.Get()); // Avoid triggering the SSO optimization by setting the string to something // larger than the internal buffer. - field.Set(&default_value, WrapString("Test long long long long value"), + field.Set(empty_default, WrapString("Test long long long long value"), &arena); EXPECT_EQ(std::string("Test long long long long value"), field.Get()); - field.Set(&default_value, std::string(""), &arena); - field.Destroy(&default_value, &arena); + field.Set(empty_default, std::string(""), &arena); + field.Destroy(empty_default, &arena); ArenaStringPtr field2; - field2.UnsafeSetDefault(&default_value); - std::string* mut = field2.Mutable(&default_value, &arena); - EXPECT_EQ(mut, field2.Mutable(&default_value, &arena)); + field2.UnsafeSetDefault(empty_default); + std::string* mut = field2.Mutable(EmptyDefault{}, &arena); + EXPECT_EQ(mut, field2.Mutable(EmptyDefault{}, &arena)); EXPECT_EQ(mut, &field2.Get()); - EXPECT_NE(&default_value, mut); - EXPECT_EQ(std::string("default"), *mut); + EXPECT_NE(empty_default, mut); + EXPECT_EQ(std::string(""), *mut); *mut = "Test long long long long value"; // ensure string allocates storage EXPECT_EQ(std::string("Test long long long long value"), field2.Get()); - field2.Destroy(&default_value, &arena); + field2.Destroy(empty_default, &arena); + + ArenaStringPtr field3; + field3.UnsafeSetDefault(nullptr); + mut = field3.Mutable(nonempty_default, &arena); + EXPECT_EQ(mut, field3.Mutable(nonempty_default, &arena)); + EXPECT_EQ(mut, &field3.Get()); + EXPECT_NE(nullptr, mut); + EXPECT_EQ(std::string("default"), *mut); + *mut = "Test long long long long value"; // ensure string allocates storage + EXPECT_EQ(std::string("Test long long long long value"), field3.Get()); + field3.Destroy(nullptr, &arena); } diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 3d5c9dee56..1cbc4b71c1 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -1224,6 +1224,7 @@ bool CommandLineInterface::AllowProto3Optional( return false; } + bool CommandLineInterface::VerifyInputFilesInDescriptors( DescriptorDatabase* database) { for (const auto& input_file : input_files_) { @@ -1242,6 +1243,7 @@ bool CommandLineInterface::VerifyInputFilesInDescriptors( << std::endl; return false; } + } return true; } @@ -1292,6 +1294,7 @@ bool CommandLineInterface::ParseInputFiles( break; } + // Enforce --direct_dependencies if (direct_dependencies_explicitly_set_) { bool indirect_imports = false; @@ -1338,6 +1341,7 @@ void CommandLineInterface::Clear() { disallow_services_ = false; direct_dependencies_explicitly_set_ = false; allow_proto3_optional_ = false; + deterministic_output_ = false; } bool CommandLineInterface::MakeProtoProtoPathRelative( @@ -1573,6 +1577,11 @@ CommandLineInterface::ParseArgumentStatus CommandLineInterface::ParseArguments( << std::endl; return PARSE_ARGUMENT_FAIL; } + if (mode_ != MODE_ENCODE && deterministic_output_) { + std::cerr << "Can only use --deterministic_output with --encode." + << std::endl; + return PARSE_ARGUMENT_FAIL; + } if (!dependency_out_name_.empty() && input_files_.size() > 1) { std::cerr << "Can only process one input file when using --dependency_out=FILE." @@ -1641,7 +1650,8 @@ bool CommandLineInterface::ParseArgument(const char* arg, std::string* name, *name == "--include_imports" || *name == "--include_source_info" || *name == "--version" || *name == "--decode_raw" || *name == "--print_free_field_numbers" || - *name == "--experimental_allow_proto3_optional") { + *name == "--experimental_allow_proto3_optional" || + *name == "--deterministic_output") { // HACK: These are the only flags that don't take a value. // They probably should not be hard-coded like this but for now it's // not worth doing better. @@ -1842,12 +1852,13 @@ CommandLineInterface::InterpretArgument(const std::string& name, std::cout << version_info_ << std::endl; } std::cout << "libprotoc " << internal::VersionString(PROTOBUF_VERSION) - << std::endl; + << PROTOBUF_VERSION_SUFFIX << std::endl; return PARSE_ARGUMENT_DONE_AND_EXIT; // Exit without running compiler. } else if (name == "--disallow_services") { disallow_services_ = true; + } else if (name == "--experimental_allow_proto3_optional") { allow_proto3_optional_ = true; @@ -1881,6 +1892,9 @@ CommandLineInterface::InterpretArgument(const std::string& name, codec_type_ = value; + } else if (name == "--deterministic_output") { + deterministic_output_ = true; + } else if (name == "--error_format") { if (value == "gcc") { error_format_ = ERROR_FORMAT_GCC; @@ -2023,6 +2037,12 @@ void CommandLineInterface::PrintHelpText() { "must\n" " be defined in PROTO_FILES or their " "imports.\n" + " --deterministic_output When using --encode, ensure map fields " + "are\n" + " deterministically ordered. Note that" + "this order is not\n" + " canonical, and changes across builds" + "or releases of protoc.\n" " --decode=MESSAGE_TYPE Read a binary message of the given " "type from\n" " standard input and write it in text " @@ -2435,7 +2455,9 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { if (mode_ == MODE_ENCODE) { // Output is binary. - if (!message->SerializePartialToZeroCopyStream(&out)) { + io::CodedOutputStream coded_out(&out); + coded_out.SetSerializationDeterministic(deterministic_output_); + if (!message->SerializePartialToCodedStream(&coded_out)) { std::cerr << "output: I/O error." << std::endl; return false; } diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index b89d4e47fc..12ba653758 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -451,6 +451,9 @@ class PROTOC_EXPORT CommandLineInterface { // Was the --experimental_allow_proto3_optional flag used? bool allow_proto3_optional_ = false; + // When using --encode, this will be passed to SetSerializationDeterministic. + bool deterministic_output_ = false; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CommandLineInterface); }; diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 5d91042845..f5d88e5022 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -40,6 +40,7 @@ #include #endif #include +#include #include #include @@ -59,10 +60,10 @@ #include #include #include +#include #include #include -#include namespace google { namespace protobuf { @@ -1387,6 +1388,7 @@ TEST_F(CommandLineInterfaceTest, AllowServicesHasService) { ExpectGenerated("test_generator", "", "foo.proto", "Foo"); } + TEST_F(CommandLineInterfaceTest, DirectDependencies_Missing_EmptyList) { CreateTempFile("foo.proto", "syntax = \"proto2\";\n" @@ -2567,7 +2569,10 @@ class EncodeDecodeTest : public testing::TestWithParam { bool Run(const std::string& command, bool specify_proto_files = true) { std::vector args; args.push_back("protoc"); - SplitStringUsing(command, " ", &args); + for (StringPiece split_piece : + Split(command, " ", true)) { + args.push_back(std::string(split_piece)); + } if (specify_proto_files) { switch (GetParam()) { case PROTO_PATH: @@ -2726,6 +2731,32 @@ TEST_P(EncodeDecodeTest, ProtoParseError) { "net/proto2/internal/no_such_file.proto: No such file or directory\n"); } +TEST_P(EncodeDecodeTest, EncodeDeterministicOutput) { + RedirectStdinFromFile(TestUtil::GetTestDataPath( + "net/proto2/internal/" + "testdata/text_format_unittest_data_oneof_implemented.txt")); + std::string args; + if (GetParam() != DESCRIPTOR_SET_IN) { + args.append( + TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto")); + } + EXPECT_TRUE(Run( + args + " --encode=protobuf_unittest.TestAllTypes --deterministic_output")); + ExpectStdoutMatchesBinaryFile(TestUtil::GetTestDataPath( + "net/proto2/internal/testdata/golden_message_oneof_implemented")); + ExpectStderrMatchesText(""); +} + +TEST_P(EncodeDecodeTest, DecodeDeterministicOutput) { + RedirectStdinFromFile(TestUtil::GetTestDataPath( + "net/proto2/internal/testdata/golden_message_oneof_implemented")); + EXPECT_FALSE( + Run(TestUtil::MaybeTranslatePath("net/proto2/internal/unittest.proto") + + " --decode=protobuf_unittest.TestAllTypes --deterministic_output")); + ExpectStderrMatchesText( + "Can only use --deterministic_output with --encode.\n"); +} + INSTANTIATE_TEST_SUITE_P(FileDescriptorSetSource, EncodeDecodeTest, testing::Values(PROTO_PATH, DESCRIPTOR_SET_IN)); } // anonymous namespace diff --git a/src/google/protobuf/compiler/cpp/cpp_field.h b/src/google/protobuf/compiler/cpp/cpp_field.h index aef9aaf304..5b2f276697 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_field.h @@ -178,11 +178,6 @@ class FieldGenerator { // are placed in the message's ByteSize() method. virtual void GenerateByteSize(io::Printer* printer) const = 0; - // Any tags about field layout decisions (such as inlining) to embed in the - // offset. - virtual uint32 CalculateFieldTag() const { return 0; } - virtual bool IsInlined() const { return false; } - void SetHasBitIndex(int32 has_bit_index); protected: diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index c27b464f95..1e3d2dad54 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -1198,7 +1198,6 @@ void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) { decls[Namespace(d, options_)].AddEnum(d); } - { NamespaceOpener ns(format); for (const auto& pair : decls) { @@ -1281,7 +1280,6 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { IncludeFile("net/proto2/public/arenastring.h", printer); IncludeFile("net/proto2/public/generated_message_table_driven.h", printer); IncludeFile("net/proto2/public/generated_message_util.h", printer); - IncludeFile("net/proto2/public/inlined_string_field.h", printer); IncludeFile("net/proto2/public/metadata_lite.h", printer); if (HasDescriptorMethods(file_, options_)) { diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 76986d0e4d..f73ed6191d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -787,25 +787,6 @@ std::string SafeFunctionName(const Descriptor* descriptor, return function_name; } -bool IsStringInlined(const FieldDescriptor* descriptor, - const Options& options) { - if (options.opensource_runtime) return false; - - // TODO(ckennelly): Handle inlining for any.proto. - if (IsAnyMessage(descriptor->containing_type(), options)) return false; - if (descriptor->containing_type()->options().map_entry()) return false; - - // We rely on has bits to distinguish field presence for release_$name$. When - // there is no hasbit, we cannot use the address of the string instance when - // the field has been inlined. - if (!HasHasbit(descriptor)) return false; - - if (options.access_info_map) { - if (descriptor->is_required()) return true; - } - return false; -} - static bool HasLazyFields(const Descriptor* descriptor, const Options& options) { for (int field_idx = 0; field_idx < descriptor->field_count(); field_idx++) { @@ -1471,8 +1452,7 @@ class ParseLoopGenerator { GetOptimizeFor(field->file(), options_) != FileOptions::LITE_RUNTIME && // For now only use arena string for strings with empty defaults. field->default_value_string().empty() && - !IsStringInlined(field, options_) && !field->real_containing_oneof() && - ctype == FieldOptions::STRING) { + !field->real_containing_oneof() && ctype == FieldOptions::STRING) { GenerateArenaString(field); } else { std::string name; diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 4ee19b8b15..a036bbc0b7 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -318,8 +318,6 @@ inline bool IsWeak(const FieldDescriptor* field, const Options& options) { return false; } -bool IsStringInlined(const FieldDescriptor* descriptor, const Options& options); - // For a string field, returns the effective ctype. If the actual ctype is // not supported, returns the default of STRING. FieldOptions::CType EffectiveStringCType(const FieldDescriptor* field, @@ -410,14 +408,6 @@ inline bool IsProto2MessageSet(const Descriptor* descriptor, descriptor->full_name() == "google.protobuf.bridge.MessageSet"; } -inline bool IsProto2MessageSetFile(const FileDescriptor* file, - const Options& options) { - return !options.opensource_runtime && - options.enforce_mode != EnforceOptimizeMode::kLiteRuntime && - !options.lite_implicit_weak_fields && - file->name() == "net/proto2/bridge/proto/message_set.proto"; -} - inline bool IsMapEntryMessage(const Descriptor* descriptor) { return descriptor->options().map_entry(); } diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 19bf4252e5..c6ab9ac5f9 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -1695,9 +1695,6 @@ uint32 CalcFieldNum(const FieldGenerator& generator, int type = field->type(); if (type == FieldDescriptor::TYPE_STRING || type == FieldDescriptor::TYPE_BYTES) { - if (generator.IsInlined()) { - type = internal::FieldMetadata::kInlinedType; - } // string field if (IsCord(field, options)) { type = internal::FieldMetadata::kCordType; @@ -2107,14 +2104,9 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { } processing_type = static_cast(field->type()); - const FieldGenerator& generator = field_generators_.get(field); if (field->type() == FieldDescriptor::TYPE_STRING) { switch (EffectiveStringCType(field, options_)) { case FieldOptions::STRING: - if (generator.IsInlined()) { - processing_type = internal::TYPE_STRING_INLINED; - break; - } break; case FieldOptions::CORD: processing_type = internal::TYPE_STRING_CORD; @@ -2126,10 +2118,6 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { } else if (field->type() == FieldDescriptor::TYPE_BYTES) { switch (EffectiveStringCType(field, options_)) { case FieldOptions::STRING: - if (generator.IsInlined()) { - processing_type = internal::TYPE_BYTES_INLINED; - break; - } break; case FieldOptions::CORD: processing_type = internal::TYPE_BYTES_CORD; @@ -2313,11 +2301,6 @@ std::pair MessageGenerator::GenerateOffsets( format("PROTOBUF_FIELD_OFFSET($classtype$, $1$_)", FieldName(field)); } - uint32 tag = field_generators_.get(field).CalculateFieldTag(); - if (tag != 0) { - format(" | $1$", tag); - } - if (!IsFieldUsed(field, options_)) { format(" | 0x80000000u, // unused\n"); } else { diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 9acc447983..beed6e5107 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -55,12 +55,31 @@ void SetStringVariables(const FieldDescriptor* descriptor, StrCat(descriptor->default_value_string().length()); std::string default_variable_string = MakeDefaultName(descriptor); (*variables)["default_variable_name"] = default_variable_string; - (*variables)["default_variable"] = + + if (!descriptor->default_value_string().empty()) { + (*variables)["lazy_variable"] = + QualifiedClassName(descriptor->containing_type(), options) + + "::" + default_variable_string; + } + + (*variables)["default_string"] = + descriptor->default_value_string().empty() + ? "::" + (*variables)["proto_ns"] + + "::internal::GetEmptyStringAlreadyInited()" + : (*variables)["lazy_variable"] + ".get()"; + (*variables)["init_value"] = descriptor->default_value_string().empty() ? "&::" + (*variables)["proto_ns"] + "::internal::GetEmptyStringAlreadyInited()" - : "&" + QualifiedClassName(descriptor->containing_type(), options) + - "::" + default_variable_string + ".get()"; + : "nullptr"; + (*variables)["default_value_tag"] = + "::" + (*variables)["proto_ns"] + "::internal::ArenaStringPtr::" + + (descriptor->default_value_string().empty() ? "Empty" : "NonEmpty") + + "Default{}"; + (*variables)["default_variable_or_tag"] = + (*variables)[descriptor->default_value_string().empty() + ? "default_value_tag" + : "lazy_variable"]; (*variables)["pointer_type"] = descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; (*variables)["null_check"] = (*variables)["DCHK"] + "(value != nullptr);\n"; @@ -75,9 +94,6 @@ void SetStringVariables(const FieldDescriptor* descriptor, } else { (*variables)["string_piece"] = "::StringPiece"; } - - (*variables)["lite"] = - HasDescriptorMethods(descriptor->file(), options) ? "" : "Lite"; } } // namespace @@ -86,9 +102,7 @@ void SetStringVariables(const FieldDescriptor* descriptor, StringFieldGenerator::StringFieldGenerator(const FieldDescriptor* descriptor, const Options& options) - : FieldGenerator(descriptor, options), - lite_(!HasDescriptorMethods(descriptor->file(), options)), - inlined_(IsStringInlined(descriptor, options)) { + : FieldGenerator(descriptor, options) { SetStringVariables(descriptor, &variables_, options); } @@ -96,23 +110,15 @@ StringFieldGenerator::~StringFieldGenerator() {} void StringFieldGenerator::GeneratePrivateMembers(io::Printer* printer) const { Formatter format(printer, variables_); - if (inlined_) { - format("::$proto_ns$::internal::InlinedStringField $name$_;\n"); - } else { - format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); - } + format("::$proto_ns$::internal::ArenaStringPtr $name$_;\n"); } void StringFieldGenerator::GenerateStaticMembers(io::Printer* printer) const { Formatter format(printer, variables_); if (!descriptor_->default_value_string().empty()) { - // We make the default instance public, so it can be initialized by - // non-friend code. format( - "public:\n" - "static ::$proto_ns$::internal::ExplicitlyConstructed" - " $default_variable_name$;\n" - "private:\n"); + "static const ::$proto_ns$::internal::LazyString" + " $default_variable_name$;\n"); } } @@ -187,7 +193,13 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( format( "inline const std::string& $classname$::$name$() const {\n" "$annotate_accessor$" - " // @@protoc_insertion_point(field_get:$full_name$)\n" + " // @@protoc_insertion_point(field_get:$full_name$)\n"); + if (!descriptor_->default_value_string().empty()) { + format( + " if ($name$_.IsDefault(nullptr)) return " + "$default_variable_name$.get();\n"); + } + format( " return _internal_$name$();\n" "}\n" "inline void $classname$::set_$name$(const std::string& value) {\n" @@ -206,21 +218,20 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( "inline void $classname$::_internal_set_$name$(const std::string& " "value) {\n" " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, value, GetArena());\n" + " $name$_.Set($default_value_tag$, value, GetArena());\n" "}\n" "inline void $classname$::set_$name$(std::string&& value) {\n" "$annotate_accessor$" " $set_hasbit$\n" - " $name$_.Set$lite$(\n" - " $default_variable$, ::std::move(value), GetArena());\n" + " $name$_.Set(\n" + " $default_value_tag$, ::std::move(value), GetArena());\n" " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" "}\n" "inline void $classname$::set_$name$(const char* value) {\n" "$annotate_accessor$" " $null_check$" " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, $string_piece$(value),\n" - " GetArena());\n" + " $name$_.Set($default_value_tag$, $string_piece$(value), GetArena());\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n"); if (!options_.opensource_runtime) { @@ -228,7 +239,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( "inline void $classname$::set_$name$(::StringPiece value) {\n" "$annotate_accessor$" " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, value,GetArena());\n" + " $name$_.Set($default_value_tag$, value,GetArena());\n" " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" "}\n"); } @@ -238,13 +249,13 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " size_t size) {\n" "$annotate_accessor$" " $set_hasbit$\n" - " $name$_.Set$lite$($default_variable$, $string_piece$(\n" + " $name$_.Set($default_value_tag$, $string_piece$(\n" " reinterpret_cast(value), size), GetArena());\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" "}\n" "inline std::string* $classname$::_internal_mutable_$name$() {\n" " $set_hasbit$\n" - " return $name$_.Mutable($default_variable$, GetArena());\n" + " return $name$_.Mutable($default_variable_or_tag$, GetArena());\n" "}\n" "inline std::string* $classname$::$release_name$() {\n" "$annotate_accessor$" @@ -256,10 +267,9 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " return nullptr;\n" " }\n" " $clear_hasbit$\n" - " return $name$_.ReleaseNonDefault(" - "$default_variable$, GetArena());\n"); + " return $name$_.ReleaseNonDefault($init_value$, GetArena());\n"); } else { - format(" return $name$_.Release($default_variable$, GetArena());\n"); + format(" return $name$_.Release($init_value$, GetArena());\n"); } format( @@ -271,7 +281,7 @@ void StringFieldGenerator::GenerateInlineAccessorDefinitions( " } else {\n" " $clear_hasbit$\n" " }\n" - " $name$_.SetAllocated($default_variable$, $name$,\n" + " $name$_.SetAllocated($init_value$, $name$,\n" " GetArena());\n" " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n" "}\n"); @@ -281,23 +291,19 @@ void StringFieldGenerator::GenerateNonInlineAccessorDefinitions( io::Printer* printer) const { Formatter format(printer, variables_); if (!descriptor_->default_value_string().empty()) { - // Initialized in GenerateDefaultInstanceAllocator. format( - "::$proto_ns$::internal::ExplicitlyConstructed " - "$classname$::$default_variable_name$;\n"); + "const ::$proto_ns$::internal::LazyString " + "$classname$::$default_variable_name$" + "{{{$default$, $default_length$}}, {nullptr}};\n"); } } void StringFieldGenerator::GenerateClearingCode(io::Printer* printer) const { Formatter format(printer, variables_); - // Two-dimension specialization here: supporting arenas or not, and default - // value is the empty string or not. Complexity here ensures the minimal - // number of branches / amount of extraneous code at runtime (given that the - // below methods are inlined one-liners)! if (descriptor_->default_value_string().empty()) { - format("$name$_.ClearToEmpty($default_variable$, GetArena());\n"); + format("$name$_.ClearToEmpty();\n"); } else { - format("$name$_.ClearToDefault($default_variable$, GetArena());\n"); + format("$name$_.ClearToDefault($lazy_variable$, GetArena());\n"); } } @@ -311,31 +317,19 @@ void StringFieldGenerator::GenerateMessageClearingCode( // If we have a hasbit, then the Clear() method of the protocol buffer // will have checked that this field is set. If so, we can avoid redundant - // checks against default_variable. + // checks against the default variable. const bool must_be_present = HasHasbit(descriptor_); - if (inlined_ && must_be_present) { - // Calling mutable_$name$() gives us a string reference and sets the has bit - // for $name$ (in proto2). We may get here when the string field is inlined - // but the string's contents have not been changed by the user, so we cannot - // make an assertion about the contents of the string and could never make - // an assertion about the string instance. - // - // For non-inlined strings, we distinguish from non-default by comparing - // instances, rather than contents. - format("$DCHK$(!$name$_.IsDefault($default_variable$));\n"); - } - if (descriptor_->default_value_string().empty()) { if (must_be_present) { format("$name$_.ClearNonDefaultToEmpty();\n"); } else { - format("$name$_.ClearToEmpty($default_variable$, GetArena());\n"); + format("$name$_.ClearToEmpty();\n"); } } else { // Clear to a non-empty default is more involved, as we try to use the // Arena if one is present and may need to reallocate the string. - format("$name$_.ClearToDefault($default_variable$, GetArena());\n"); + format("$name$_.ClearToDefault($lazy_variable$, GetArena());\n "); } } @@ -347,23 +341,12 @@ void StringFieldGenerator::GenerateMergingCode(io::Printer* printer) const { void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (inlined_) { - format("$name$_.Swap(&other->$name$_);\n"); - } else { - format("$name$_.Swap(&other->$name$_, $default_variable$, GetArena());\n"); - } + format("$name$_.Swap(&other->$name$_, $init_value$, GetArena());\n"); } void StringFieldGenerator::GenerateConstructorCode(io::Printer* printer) const { Formatter format(printer, variables_); - // TODO(ckennelly): Construct non-empty strings as part of the initializer - // list. - if (inlined_ && descriptor_->default_value_string().empty()) { - // Automatic initialization will construct the string. - return; - } - - format("$name$_.UnsafeSetDefault($default_variable$);\n"); + format("$name$_.UnsafeSetDefault($init_value$);\n"); } void StringFieldGenerator::GenerateCopyConstructorCode( @@ -381,7 +364,7 @@ void StringFieldGenerator::GenerateCopyConstructorCode( // TODO(gpike): improve this format( - "$name$_.Set$lite$($default_variable$, from._internal_$name$(),\n" + "$name$_.Set($default_value_tag$, from._internal_$name$(), \n" " GetArena());\n"); format.Outdent(); @@ -390,40 +373,7 @@ void StringFieldGenerator::GenerateCopyConstructorCode( void StringFieldGenerator::GenerateDestructorCode(io::Printer* printer) const { Formatter format(printer, variables_); - if (inlined_) { - // The destructor is automatically invoked. - return; - } - - format("$name$_.DestroyNoArena($default_variable$);\n"); -} - -bool StringFieldGenerator::GenerateArenaDestructorCode( - io::Printer* printer) const { - Formatter format(printer, variables_); - if (!inlined_) { - return false; - } - - format("_this->$name$_.DestroyNoArena($default_variable$);\n"); - return true; -} - -void StringFieldGenerator::GenerateDefaultInstanceAllocator( - io::Printer* printer) const { - Formatter format(printer, variables_); - if (!descriptor_->default_value_string().empty()) { - format( - "$ns$::$classname$::$default_variable_name$.DefaultConstruct();\n" - "*$ns$::$classname$::$default_variable_name$.get_mutable() = " - "std::string($default$, $default_length$);\n" - "::$proto_ns$::internal::OnShutdownDestroyString(\n" - " $ns$::$classname$::$default_variable_name$.get_mutable());\n"); - } -} - -bool StringFieldGenerator::MergeFromCodedStreamNeedsArena() const { - return !lite_ && !inlined_ && !options_.opensource_runtime; + format("$name$_.DestroyNoArena($init_value$);\n"); } void StringFieldGenerator::GenerateSerializeWithCachedSizesToArray( @@ -449,17 +399,11 @@ void StringFieldGenerator::GenerateByteSize(io::Printer* printer) const { " this->_internal_$name$());\n"); } -uint32 StringFieldGenerator::CalculateFieldTag() const { - return inlined_ ? 1 : 0; -} - // =================================================================== StringOneofFieldGenerator::StringOneofFieldGenerator( const FieldDescriptor* descriptor, const Options& options) : StringFieldGenerator(descriptor, options) { - inlined_ = false; - SetCommonOneofFieldVariables(descriptor, &variables_); variables_["field_name"] = UnderscoresToCamelCase(descriptor->name(), true); variables_["oneof_index"] = @@ -491,16 +435,16 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (_internal_has_$name$()) {\n" " return $field_member$.Get();\n" " }\n" - " return *$default_variable$;\n" + " return $default_string$;\n" "}\n" "inline void $classname$::_internal_set_$name$(const std::string& " "value) {\n" " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" " }\n" - " $field_member$.Set$lite$($default_variable$, value, GetArena());\n" + " $field_member$.Set($default_value_tag$, value, GetArena());\n" "}\n" "inline void $classname$::set_$name$(std::string&& value) {\n" "$annotate_accessor$" @@ -508,10 +452,10 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" " }\n" - " $field_member$.Set$lite$(\n" - " $default_variable$, ::std::move(value), GetArena());\n" + " $field_member$.Set(\n" + " $default_value_tag$, ::std::move(value), GetArena());\n" " // @@protoc_insertion_point(field_set_rvalue:$full_name$)\n" "}\n" "inline void $classname$::set_$name$(const char* value) {\n" @@ -520,9 +464,9 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" " }\n" - " $field_member$.Set$lite$($default_variable$,\n" + " $field_member$.Set($default_value_tag$,\n" " $string_piece$(value), GetArena());\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n"); @@ -533,10 +477,9 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" " }\n" - " $field_member$.Set$lite$($default_variable$, value,\n" - " GetArena());\n" + " $field_member$.Set($default_value_tag$, value, GetArena());\n" " // @@protoc_insertion_point(field_set_string_piece:$full_name$)\n" "}\n"); } @@ -548,10 +491,10 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" " }\n" - " $field_member$.Set$lite$(\n" - " $default_variable$, $string_piece$(\n" + " $field_member$.Set(\n" + " $default_value_tag$, $string_piece$(\n" " reinterpret_cast(value), size),\n" " GetArena());\n" " // @@protoc_insertion_point(field_set_pointer:$full_name$)\n" @@ -560,16 +503,17 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( " if (!_internal_has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" - " $field_member$.UnsafeSetDefault($default_variable$);\n" + " $field_member$.UnsafeSetDefault($init_value$);\n" " }\n" - " return $field_member$.Mutable($default_variable$, GetArena());\n" + " return $field_member$.Mutable(\n" + " $default_variable_or_tag$, GetArena());\n" "}\n" "inline std::string* $classname$::$release_name$() {\n" "$annotate_accessor$" " // @@protoc_insertion_point(field_release:$full_name$)\n" " if (_internal_has_$name$()) {\n" " clear_has_$oneof_name$();\n" - " return $field_member$.Release($default_variable$, GetArena());\n" + " return $field_member$.ReleaseNonDefault($init_value$, GetArena());\n" " } else {\n" " return nullptr;\n" " }\n" @@ -594,7 +538,7 @@ void StringOneofFieldGenerator::GenerateInlineAccessorDefinitions( void StringOneofFieldGenerator::GenerateClearingCode( io::Printer* printer) const { Formatter format(printer, variables_); - format("$field_member$.Destroy($default_variable$, GetArena());\n"); + format("$field_member$.Destroy($default_value_tag$, GetArena());\n"); } void StringOneofFieldGenerator::GenerateMessageClearingCode( @@ -609,10 +553,7 @@ void StringOneofFieldGenerator::GenerateSwappingCode( void StringOneofFieldGenerator::GenerateConstructorCode( io::Printer* printer) const { - Formatter format(printer, variables_); - format( - "$ns$::_$classname$_default_instance_.$name$_.UnsafeSetDefault(\n" - " $default_variable$);\n"); + // Nothing required here. } // =================================================================== diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h index 0192b3dd6d..91424d221c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h @@ -63,18 +63,8 @@ class StringFieldGenerator : public FieldGenerator { void GenerateConstructorCode(io::Printer* printer) const; void GenerateCopyConstructorCode(io::Printer* printer) const; void GenerateDestructorCode(io::Printer* printer) const; - bool GenerateArenaDestructorCode(io::Printer* printer) const; - void GenerateDefaultInstanceAllocator(io::Printer* printer) const; void GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const; void GenerateByteSize(io::Printer* printer) const; - uint32 CalculateFieldTag() const; - bool IsInlined() const { return inlined_; } - - bool MergeFromCodedStreamNeedsArena() const; - - protected: - const bool lite_; - bool inlined_; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringFieldGenerator); diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc index 7eb9c75485..d96ac7d772 100644 --- a/src/google/protobuf/compiler/java/java_enum_field.cc +++ b/src/google/protobuf/compiler/java/java_enum_field.cc @@ -81,7 +81,7 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, // with v2.5.0/v2.6.1, and remove the @SuppressWarnings annotations. (*variables)["for_number"] = "valueOf"; - if (SupportFieldPresence(descriptor)) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); @@ -145,7 +145,7 @@ ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator( ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {} int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc index 23aea9b20b..b0b3b78cc6 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -83,7 +83,7 @@ void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["required"] = descriptor->is_required() ? "true" : "false"; - if (SupportFieldPresence(descriptor)) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); @@ -137,7 +137,7 @@ ImmutableEnumFieldLiteGenerator::ImmutableEnumFieldLiteGenerator( ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {} int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } void ImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers( diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 0192e4bc67..6623595b11 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -1355,7 +1355,6 @@ void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) { } } - void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) { printer->Print( "private static String getTypeUrl(\n" diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index f0b3d0959e..f06e8fb203 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -133,7 +133,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } (*variables)["on_changed"] = "onChanged();"; - if (SupportFieldPresence(descriptor)) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); @@ -195,7 +195,7 @@ ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator( ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {} int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const { diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc index 53366b295a..59dba76cc0 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -140,7 +140,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, (*variables)["fixed_size"] = StrCat(fixed_size); } - if (SupportFieldPresence(descriptor)) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); @@ -188,7 +188,7 @@ ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator( ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {} int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers( diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc index 37e81b1100..548f898e46 100644 --- a/src/google/protobuf/compiler/java/java_string_field.cc +++ b/src/google/protobuf/compiler/java/java_string_field.cc @@ -90,7 +90,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["on_changed"] = "onChanged();"; - if (SupportFieldPresence(descriptor)) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex); @@ -147,7 +147,7 @@ ImmutableStringFieldGenerator::ImmutableStringFieldGenerator( ImmutableStringFieldGenerator::~ImmutableStringFieldGenerator() {} int ImmutableStringFieldGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } int ImmutableStringFieldGenerator::GetNumBitsForBuilder() const { diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc index 432a789551..06a3c25bd9 100644 --- a/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -85,7 +85,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, descriptor->options().deprecated() ? "@java.lang.Deprecated " : ""; (*variables)["required"] = descriptor->is_required() ? "true" : "false"; - if (SupportFieldPresence(descriptor)) { + if (HasHasbit(descriptor)) { // For singular messages and builders, one bit is used for the hasField bit. (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex); @@ -127,7 +127,7 @@ ImmutableStringFieldLiteGenerator::ImmutableStringFieldLiteGenerator( ImmutableStringFieldLiteGenerator::~ImmutableStringFieldLiteGenerator() {} int ImmutableStringFieldLiteGenerator::GetNumBitsForMessage() const { - return SupportFieldPresence(descriptor_) ? 1 : 0; + return HasHasbit(descriptor_) ? 1 : 0; } // A note about how strings are handled. In the SPEED and CODE_SIZE runtimes, diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index b463622d4a..3abb5c0b13 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -119,7 +119,7 @@ void MockCodeGenerator::ExpectGenerated( std::vector insertion_list; if (!insertions.empty()) { - SplitStringUsing(insertions, ",", &insertion_list); + insertion_list = Split(insertions, ",", true); } EXPECT_EQ(lines.size(), 3 + insertion_list.size() * 2); @@ -250,12 +250,10 @@ bool MockCodeGenerator::Generate(const FileDescriptor* file, bool insert_endlines = HasPrefixString(parameter, "insert_endlines="); if (insert_endlines || HasPrefixString(parameter, "insert=")) { - std::vector insert_into; - - SplitStringUsing( + std::vector insert_into = Split( StripPrefixString( parameter, insert_endlines ? "insert_endlines=" : "insert="), - ",", &insert_into); + ",", true); for (size_t i = 0; i < insert_into.size(); i++) { { diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 2b39bc40e3..a173a78b49 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -260,7 +260,7 @@ Version::Version(const Version& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); suffix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_suffix()) { - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_suffix(), + suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_suffix(), GetArena()); } ::memcpy(&major_, &from.major_, @@ -593,7 +593,7 @@ CodeGeneratorRequest::CodeGeneratorRequest(const CodeGeneratorRequest& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); parameter_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_parameter()) { - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_parameter(), + parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_parameter(), GetArena()); } if (from._internal_has_compiler_version()) { @@ -946,17 +946,17 @@ CodeGeneratorResponse_File::CodeGeneratorResponse_File(const CodeGeneratorRespon _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } insertion_point_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_insertion_point()) { - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_insertion_point(), + insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_insertion_point(), GetArena()); } content_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_content()) { - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_content(), + content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_content(), GetArena()); } if (from._internal_has_generated_code_info()) { @@ -1302,7 +1302,7 @@ CodeGeneratorResponse::CodeGeneratorResponse(const CodeGeneratorResponse& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); error_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_error()) { - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_error(), + error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_error(), GetArena()); } supported_features_ = from.supported_features_; diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 09e3bbb171..ee1308c6a0 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -1076,7 +1075,7 @@ inline bool Version::has_suffix() const { return _internal_has_suffix(); } inline void Version::clear_suffix() { - suffix_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + suffix_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& Version::suffix() const { @@ -1096,31 +1095,30 @@ inline const std::string& Version::_internal_suffix() const { } inline void Version::_internal_set_suffix(const std::string& value) { _has_bits_[0] |= 0x00000001u; - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Version::set_suffix(std::string&& value) { _has_bits_[0] |= 0x00000001u; suffix_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.Version.suffix) } inline void Version::set_suffix(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix) } inline void Version::set_suffix(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - suffix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + suffix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.Version.suffix) } inline std::string* Version::_internal_mutable_suffix() { _has_bits_[0] |= 0x00000001u; - return suffix_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return suffix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Version::release_suffix() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.Version.suffix) @@ -1228,7 +1226,7 @@ inline bool CodeGeneratorRequest::has_parameter() const { return _internal_has_parameter(); } inline void CodeGeneratorRequest::clear_parameter() { - parameter_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + parameter_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorRequest::parameter() const { @@ -1248,31 +1246,30 @@ inline const std::string& CodeGeneratorRequest::_internal_parameter() const { } inline void CodeGeneratorRequest::_internal_set_parameter(const std::string& value) { _has_bits_[0] |= 0x00000001u; - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorRequest::set_parameter(std::string&& value) { _has_bits_[0] |= 0x00000001u; parameter_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorRequest.parameter) } inline void CodeGeneratorRequest::set_parameter(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter) } inline void CodeGeneratorRequest::set_parameter(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - parameter_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + parameter_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorRequest.parameter) } inline std::string* CodeGeneratorRequest::_internal_mutable_parameter() { _has_bits_[0] |= 0x00000001u; - return parameter_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return parameter_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorRequest::release_parameter() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1425,7 +1422,7 @@ inline bool CodeGeneratorResponse_File::has_name() const { return _internal_has_name(); } inline void CodeGeneratorResponse_File::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorResponse_File::name() const { @@ -1445,31 +1442,30 @@ inline const std::string& CodeGeneratorResponse_File::_internal_name() const { } inline void CodeGeneratorResponse_File::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorResponse_File::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.name) } inline void CodeGeneratorResponse_File::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name) } inline void CodeGeneratorResponse_File::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.name) } inline std::string* CodeGeneratorResponse_File::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorResponse_File::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1499,7 +1495,7 @@ inline bool CodeGeneratorResponse_File::has_insertion_point() const { return _internal_has_insertion_point(); } inline void CodeGeneratorResponse_File::clear_insertion_point() { - insertion_point_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + insertion_point_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& CodeGeneratorResponse_File::insertion_point() const { @@ -1519,31 +1515,30 @@ inline const std::string& CodeGeneratorResponse_File::_internal_insertion_point( } inline void CodeGeneratorResponse_File::_internal_set_insertion_point(const std::string& value) { _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorResponse_File::set_insertion_point(std::string&& value) { _has_bits_[0] |= 0x00000002u; insertion_point_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } inline void CodeGeneratorResponse_File::set_insertion_point(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - insertion_point_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + insertion_point_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) } inline std::string* CodeGeneratorResponse_File::_internal_mutable_insertion_point() { _has_bits_[0] |= 0x00000002u; - return insertion_point_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return insertion_point_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorResponse_File::release_insertion_point() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1573,7 +1568,7 @@ inline bool CodeGeneratorResponse_File::has_content() const { return _internal_has_content(); } inline void CodeGeneratorResponse_File::clear_content() { - content_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + content_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& CodeGeneratorResponse_File::content() const { @@ -1593,31 +1588,30 @@ inline const std::string& CodeGeneratorResponse_File::_internal_content() const } inline void CodeGeneratorResponse_File::_internal_set_content(const std::string& value) { _has_bits_[0] |= 0x00000004u; - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorResponse_File::set_content(std::string&& value) { _has_bits_[0] |= 0x00000004u; content_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.File.content) } inline void CodeGeneratorResponse_File::set_content(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content) } inline void CodeGeneratorResponse_File::set_content(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - content_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + content_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.File.content) } inline std::string* CodeGeneratorResponse_File::_internal_mutable_content() { _has_bits_[0] |= 0x00000004u; - return content_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return content_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorResponse_File::release_content() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1730,7 +1724,7 @@ inline bool CodeGeneratorResponse::has_error() const { return _internal_has_error(); } inline void CodeGeneratorResponse::clear_error() { - error_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + error_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& CodeGeneratorResponse::error() const { @@ -1750,31 +1744,30 @@ inline const std::string& CodeGeneratorResponse::_internal_error() const { } inline void CodeGeneratorResponse::_internal_set_error(const std::string& value) { _has_bits_[0] |= 0x00000001u; - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void CodeGeneratorResponse::set_error(std::string&& value) { _has_bits_[0] |= 0x00000001u; error_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.CodeGeneratorResponse.error) } inline void CodeGeneratorResponse::set_error(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error) } inline void CodeGeneratorResponse::set_error(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - error_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + error_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.CodeGeneratorResponse.error) } inline std::string* CodeGeneratorResponse::_internal_mutable_error() { _has_bits_[0] |= 0x00000001u; - return error_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return error_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* CodeGeneratorResponse::release_error() { // @@protoc_insertion_point(field_release:google.protobuf.compiler.CodeGeneratorResponse.error) diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index c3d96555bd..d1d0828b58 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -4052,7 +4052,8 @@ bool DescriptorBuilder::AddSymbol(const std::string& full_name, // Symbol seems to have been defined in a different file. AddError(full_name, proto, DescriptorPool::ErrorCollector::NAME, "\"" + full_name + "\" is already defined in file \"" + - other_file->name() + "\"."); + (other_file == nullptr ? "null" : other_file->name()) + + "\"."); } return false; } diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index e3eba97fcd..288ff0659a 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -1605,17 +1605,17 @@ FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_package()) { - package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_package(), + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_package(), GetArena()); } syntax_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_syntax()) { - syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_syntax(), + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_syntax(), GetArena()); } if (from._internal_has_options()) { @@ -2807,7 +2807,7 @@ DescriptorProto::DescriptorProto(const DescriptorProto& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } if (from._internal_has_options()) { @@ -3588,27 +3588,27 @@ FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } extendee_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_extendee()) { - extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_extendee(), + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_extendee(), GetArena()); } type_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_type_name()) { - type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_type_name(), + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_name(), GetArena()); } default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_default_value()) { - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_default_value(), + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_default_value(), GetArena()); } json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_json_name()) { - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_json_name(), + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_json_name(), GetArena()); } if (from._internal_has_options()) { @@ -4190,7 +4190,7 @@ OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } if (from._internal_has_options()) { @@ -4728,7 +4728,7 @@ EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } if (from._internal_has_options()) { @@ -5107,7 +5107,7 @@ EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProt _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } if (from._internal_has_options()) { @@ -5421,7 +5421,7 @@ ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& fro _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } if (from._internal_has_options()) { @@ -5742,17 +5742,17 @@ MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } input_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_input_type()) { - input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_input_type(), + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_input_type(), GetArena()); } output_type_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_output_type()) { - output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_output_type(), + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_output_type(), GetArena()); } if (from._internal_has_options()) { @@ -6215,52 +6215,52 @@ FileOptions::FileOptions(const FileOptions& from) _extensions_.MergeFrom(from._extensions_); java_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_java_package()) { - java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_java_package(), + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_java_package(), GetArena()); } java_outer_classname_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_java_outer_classname()) { - java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_java_outer_classname(), + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_java_outer_classname(), GetArena()); } go_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_go_package()) { - go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_go_package(), + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_go_package(), GetArena()); } objc_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_objc_class_prefix()) { - objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_objc_class_prefix(), + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_objc_class_prefix(), GetArena()); } csharp_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_csharp_namespace()) { - csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_csharp_namespace(), + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_csharp_namespace(), GetArena()); } swift_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_swift_prefix()) { - swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_swift_prefix(), + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_swift_prefix(), GetArena()); } php_class_prefix_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_php_class_prefix()) { - php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_php_class_prefix(), + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_class_prefix(), GetArena()); } php_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_php_namespace()) { - php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_php_namespace(), + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_namespace(), GetArena()); } php_metadata_namespace_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_php_metadata_namespace()) { - php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_php_metadata_namespace(), + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_php_metadata_namespace(), GetArena()); } ruby_package_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_ruby_package()) { - ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_ruby_package(), + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_ruby_package(), GetArena()); } ::memcpy(&java_multiple_files_, &from.java_multiple_files_, @@ -9270,7 +9270,7 @@ UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOp _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_part_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_name_part()) { - name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name_part(), + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name_part(), GetArena()); } is_extension_ = from.is_extension_; @@ -9558,17 +9558,17 @@ UninterpretedOption::UninterpretedOption(const UninterpretedOption& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); identifier_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_identifier_value()) { - identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_identifier_value(), + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_identifier_value(), GetArena()); } string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_string_value()) { - string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_string_value(), + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_string_value(), GetArena()); } aggregate_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_aggregate_value()) { - aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_aggregate_value(), + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_aggregate_value(), GetArena()); } ::memcpy(&positive_int_value_, &from.positive_int_value_, @@ -9993,12 +9993,12 @@ SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); leading_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_leading_comments()) { - leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_leading_comments(), + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_leading_comments(), GetArena()); } trailing_comments_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_trailing_comments()) { - trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_trailing_comments(), + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_trailing_comments(), GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceCodeInfo.Location) @@ -10585,7 +10585,7 @@ GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation(const GeneratedCodeIn _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); source_file_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (from._internal_has_source_file()) { - source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_source_file(), + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_source_file(), GetArena()); } ::memcpy(&begin_, &from.begin_, diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index feaae115cb..20c412aefe 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -6623,7 +6622,7 @@ inline bool FileDescriptorProto::has_name() const { return _internal_has_name(); } inline void FileDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& FileDescriptorProto::name() const { @@ -6643,31 +6642,30 @@ inline const std::string& FileDescriptorProto::_internal_name() const { } inline void FileDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.name) } inline void FileDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name) } inline void FileDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.name) } inline std::string* FileDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.name) @@ -6697,7 +6695,7 @@ inline bool FileDescriptorProto::has_package() const { return _internal_has_package(); } inline void FileDescriptorProto::clear_package() { - package_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + package_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& FileDescriptorProto::package() const { @@ -6717,31 +6715,30 @@ inline const std::string& FileDescriptorProto::_internal_package() const { } inline void FileDescriptorProto::_internal_set_package(const std::string& value) { _has_bits_[0] |= 0x00000002u; - package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileDescriptorProto::set_package(std::string&& value) { _has_bits_[0] |= 0x00000002u; package_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.package) } inline void FileDescriptorProto::set_package(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package) } inline void FileDescriptorProto::set_package(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.package) } inline std::string* FileDescriptorProto::_internal_mutable_package() { _has_bits_[0] |= 0x00000002u; - return package_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileDescriptorProto::release_package() { // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.package) @@ -7261,7 +7258,7 @@ inline bool FileDescriptorProto::has_syntax() const { return _internal_has_syntax(); } inline void FileDescriptorProto::clear_syntax() { - syntax_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + syntax_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& FileDescriptorProto::syntax() const { @@ -7281,31 +7278,30 @@ inline const std::string& FileDescriptorProto::_internal_syntax() const { } inline void FileDescriptorProto::_internal_set_syntax(const std::string& value) { _has_bits_[0] |= 0x00000004u; - syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileDescriptorProto::set_syntax(std::string&& value) { _has_bits_[0] |= 0x00000004u; syntax_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileDescriptorProto.syntax) } inline void FileDescriptorProto::set_syntax(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax) } inline void FileDescriptorProto::set_syntax(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - syntax_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + syntax_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileDescriptorProto.syntax) } inline std::string* FileDescriptorProto::_internal_mutable_syntax() { _has_bits_[0] |= 0x00000004u; - return syntax_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return syntax_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileDescriptorProto::release_syntax() { // @@protoc_insertion_point(field_release:google.protobuf.FileDescriptorProto.syntax) @@ -7542,7 +7538,7 @@ inline bool DescriptorProto::has_name() const { return _internal_has_name(); } inline void DescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& DescriptorProto::name() const { @@ -7562,31 +7558,30 @@ inline const std::string& DescriptorProto::_internal_name() const { } inline void DescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void DescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.DescriptorProto.name) } inline void DescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name) } inline void DescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.DescriptorProto.name) } inline std::string* DescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* DescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.DescriptorProto.name) @@ -8093,7 +8088,7 @@ inline bool FieldDescriptorProto::has_name() const { return _internal_has_name(); } inline void FieldDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& FieldDescriptorProto::name() const { @@ -8113,31 +8108,30 @@ inline const std::string& FieldDescriptorProto::_internal_name() const { } inline void FieldDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.name) } inline void FieldDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name) } inline void FieldDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.name) } inline std::string* FieldDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.name) @@ -8253,7 +8247,7 @@ inline bool FieldDescriptorProto::has_type_name() const { return _internal_has_type_name(); } inline void FieldDescriptorProto::clear_type_name() { - type_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + type_name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& FieldDescriptorProto::type_name() const { @@ -8273,31 +8267,30 @@ inline const std::string& FieldDescriptorProto::_internal_type_name() const { } inline void FieldDescriptorProto::_internal_set_type_name(const std::string& value) { _has_bits_[0] |= 0x00000004u; - type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_type_name(std::string&& value) { _has_bits_[0] |= 0x00000004u; type_name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.type_name) } inline void FieldDescriptorProto::set_type_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name) } inline void FieldDescriptorProto::set_type_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - type_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + type_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.type_name) } inline std::string* FieldDescriptorProto::_internal_mutable_type_name() { _has_bits_[0] |= 0x00000004u; - return type_name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return type_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_type_name() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.type_name) @@ -8327,7 +8320,7 @@ inline bool FieldDescriptorProto::has_extendee() const { return _internal_has_extendee(); } inline void FieldDescriptorProto::clear_extendee() { - extendee_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + extendee_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& FieldDescriptorProto::extendee() const { @@ -8347,31 +8340,30 @@ inline const std::string& FieldDescriptorProto::_internal_extendee() const { } inline void FieldDescriptorProto::_internal_set_extendee(const std::string& value) { _has_bits_[0] |= 0x00000002u; - extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_extendee(std::string&& value) { _has_bits_[0] |= 0x00000002u; extendee_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.extendee) } inline void FieldDescriptorProto::set_extendee(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee) } inline void FieldDescriptorProto::set_extendee(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - extendee_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + extendee_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.extendee) } inline std::string* FieldDescriptorProto::_internal_mutable_extendee() { _has_bits_[0] |= 0x00000002u; - return extendee_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return extendee_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_extendee() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.extendee) @@ -8401,7 +8393,7 @@ inline bool FieldDescriptorProto::has_default_value() const { return _internal_has_default_value(); } inline void FieldDescriptorProto::clear_default_value() { - default_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + default_value_.ClearToEmpty(); _has_bits_[0] &= ~0x00000008u; } inline const std::string& FieldDescriptorProto::default_value() const { @@ -8421,31 +8413,30 @@ inline const std::string& FieldDescriptorProto::_internal_default_value() const } inline void FieldDescriptorProto::_internal_set_default_value(const std::string& value) { _has_bits_[0] |= 0x00000008u; - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_default_value(std::string&& value) { _has_bits_[0] |= 0x00000008u; default_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.default_value) } inline void FieldDescriptorProto::set_default_value(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000008u; - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value) } inline void FieldDescriptorProto::set_default_value(const char* value, size_t size) { _has_bits_[0] |= 0x00000008u; - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.default_value) } inline std::string* FieldDescriptorProto::_internal_mutable_default_value() { _has_bits_[0] |= 0x00000008u; - return default_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_default_value() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.default_value) @@ -8503,7 +8494,7 @@ inline bool FieldDescriptorProto::has_json_name() const { return _internal_has_json_name(); } inline void FieldDescriptorProto::clear_json_name() { - json_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + json_name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000010u; } inline const std::string& FieldDescriptorProto::json_name() const { @@ -8523,31 +8514,30 @@ inline const std::string& FieldDescriptorProto::_internal_json_name() const { } inline void FieldDescriptorProto::_internal_set_json_name(const std::string& value) { _has_bits_[0] |= 0x00000010u; - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FieldDescriptorProto::set_json_name(std::string&& value) { _has_bits_[0] |= 0x00000010u; json_name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FieldDescriptorProto.json_name) } inline void FieldDescriptorProto::set_json_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000010u; - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name) } inline void FieldDescriptorProto::set_json_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000010u; - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FieldDescriptorProto.json_name) } inline std::string* FieldDescriptorProto::_internal_mutable_json_name() { _has_bits_[0] |= 0x00000010u; - return json_name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return json_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FieldDescriptorProto::release_json_name() { // @@protoc_insertion_point(field_release:google.protobuf.FieldDescriptorProto.json_name) @@ -8692,7 +8682,7 @@ inline bool OneofDescriptorProto::has_name() const { return _internal_has_name(); } inline void OneofDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& OneofDescriptorProto::name() const { @@ -8712,31 +8702,30 @@ inline const std::string& OneofDescriptorProto::_internal_name() const { } inline void OneofDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void OneofDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.OneofDescriptorProto.name) } inline void OneofDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name) } inline void OneofDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.OneofDescriptorProto.name) } inline std::string* OneofDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* OneofDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.OneofDescriptorProto.name) @@ -8913,7 +8902,7 @@ inline bool EnumDescriptorProto::has_name() const { return _internal_has_name(); } inline void EnumDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& EnumDescriptorProto::name() const { @@ -8933,31 +8922,30 @@ inline const std::string& EnumDescriptorProto::_internal_name() const { } inline void EnumDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void EnumDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumDescriptorProto.name) } inline void EnumDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name) } inline void EnumDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumDescriptorProto.name) } inline std::string* EnumDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* EnumDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.EnumDescriptorProto.name) @@ -9226,7 +9214,7 @@ inline bool EnumValueDescriptorProto::has_name() const { return _internal_has_name(); } inline void EnumValueDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& EnumValueDescriptorProto::name() const { @@ -9246,31 +9234,30 @@ inline const std::string& EnumValueDescriptorProto::_internal_name() const { } inline void EnumValueDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void EnumValueDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumValueDescriptorProto.name) } inline void EnumValueDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name) } inline void EnumValueDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValueDescriptorProto.name) } inline std::string* EnumValueDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* EnumValueDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.EnumValueDescriptorProto.name) @@ -9415,7 +9402,7 @@ inline bool ServiceDescriptorProto::has_name() const { return _internal_has_name(); } inline void ServiceDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& ServiceDescriptorProto::name() const { @@ -9435,31 +9422,30 @@ inline const std::string& ServiceDescriptorProto::_internal_name() const { } inline void ServiceDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void ServiceDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.ServiceDescriptorProto.name) } inline void ServiceDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name) } inline void ServiceDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.ServiceDescriptorProto.name) } inline std::string* ServiceDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* ServiceDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.ServiceDescriptorProto.name) @@ -9615,7 +9601,7 @@ inline bool MethodDescriptorProto::has_name() const { return _internal_has_name(); } inline void MethodDescriptorProto::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& MethodDescriptorProto::name() const { @@ -9635,31 +9621,30 @@ inline const std::string& MethodDescriptorProto::_internal_name() const { } inline void MethodDescriptorProto::_internal_set_name(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void MethodDescriptorProto::set_name(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.name) } inline void MethodDescriptorProto::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name) } inline void MethodDescriptorProto::set_name(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.name) } inline std::string* MethodDescriptorProto::_internal_mutable_name() { _has_bits_[0] |= 0x00000001u; - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* MethodDescriptorProto::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.name) @@ -9689,7 +9674,7 @@ inline bool MethodDescriptorProto::has_input_type() const { return _internal_has_input_type(); } inline void MethodDescriptorProto::clear_input_type() { - input_type_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + input_type_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& MethodDescriptorProto::input_type() const { @@ -9709,31 +9694,30 @@ inline const std::string& MethodDescriptorProto::_internal_input_type() const { } inline void MethodDescriptorProto::_internal_set_input_type(const std::string& value) { _has_bits_[0] |= 0x00000002u; - input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void MethodDescriptorProto::set_input_type(std::string&& value) { _has_bits_[0] |= 0x00000002u; input_type_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.input_type) } inline void MethodDescriptorProto::set_input_type(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type) } inline void MethodDescriptorProto::set_input_type(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - input_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + input_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.input_type) } inline std::string* MethodDescriptorProto::_internal_mutable_input_type() { _has_bits_[0] |= 0x00000002u; - return input_type_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return input_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* MethodDescriptorProto::release_input_type() { // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.input_type) @@ -9763,7 +9747,7 @@ inline bool MethodDescriptorProto::has_output_type() const { return _internal_has_output_type(); } inline void MethodDescriptorProto::clear_output_type() { - output_type_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + output_type_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& MethodDescriptorProto::output_type() const { @@ -9783,31 +9767,30 @@ inline const std::string& MethodDescriptorProto::_internal_output_type() const { } inline void MethodDescriptorProto::_internal_set_output_type(const std::string& value) { _has_bits_[0] |= 0x00000004u; - output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void MethodDescriptorProto::set_output_type(std::string&& value) { _has_bits_[0] |= 0x00000004u; output_type_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.MethodDescriptorProto.output_type) } inline void MethodDescriptorProto::set_output_type(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type) } inline void MethodDescriptorProto::set_output_type(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - output_type_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + output_type_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.MethodDescriptorProto.output_type) } inline std::string* MethodDescriptorProto::_internal_mutable_output_type() { _has_bits_[0] |= 0x00000004u; - return output_type_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return output_type_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* MethodDescriptorProto::release_output_type() { // @@protoc_insertion_point(field_release:google.protobuf.MethodDescriptorProto.output_type) @@ -9980,7 +9963,7 @@ inline bool FileOptions::has_java_package() const { return _internal_has_java_package(); } inline void FileOptions::clear_java_package() { - java_package_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + java_package_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& FileOptions::java_package() const { @@ -10000,31 +9983,30 @@ inline const std::string& FileOptions::_internal_java_package() const { } inline void FileOptions::_internal_set_java_package(const std::string& value) { _has_bits_[0] |= 0x00000001u; - java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_java_package(std::string&& value) { _has_bits_[0] |= 0x00000001u; java_package_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.java_package) } inline void FileOptions::set_java_package(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package) } inline void FileOptions::set_java_package(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - java_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + java_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_package) } inline std::string* FileOptions::_internal_mutable_java_package() { _has_bits_[0] |= 0x00000001u; - return java_package_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return java_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_java_package() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_package) @@ -10054,7 +10036,7 @@ inline bool FileOptions::has_java_outer_classname() const { return _internal_has_java_outer_classname(); } inline void FileOptions::clear_java_outer_classname() { - java_outer_classname_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + java_outer_classname_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& FileOptions::java_outer_classname() const { @@ -10074,31 +10056,30 @@ inline const std::string& FileOptions::_internal_java_outer_classname() const { } inline void FileOptions::_internal_set_java_outer_classname(const std::string& value) { _has_bits_[0] |= 0x00000002u; - java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_java_outer_classname(std::string&& value) { _has_bits_[0] |= 0x00000002u; java_outer_classname_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.java_outer_classname) } inline void FileOptions::set_java_outer_classname(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname) } inline void FileOptions::set_java_outer_classname(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - java_outer_classname_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + java_outer_classname_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.java_outer_classname) } inline std::string* FileOptions::_internal_mutable_java_outer_classname() { _has_bits_[0] |= 0x00000002u; - return java_outer_classname_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return java_outer_classname_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_java_outer_classname() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.java_outer_classname) @@ -10241,7 +10222,7 @@ inline bool FileOptions::has_go_package() const { return _internal_has_go_package(); } inline void FileOptions::clear_go_package() { - go_package_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + go_package_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& FileOptions::go_package() const { @@ -10261,31 +10242,30 @@ inline const std::string& FileOptions::_internal_go_package() const { } inline void FileOptions::_internal_set_go_package(const std::string& value) { _has_bits_[0] |= 0x00000004u; - go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_go_package(std::string&& value) { _has_bits_[0] |= 0x00000004u; go_package_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.go_package) } inline void FileOptions::set_go_package(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package) } inline void FileOptions::set_go_package(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - go_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + go_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.go_package) } inline std::string* FileOptions::_internal_mutable_go_package() { _has_bits_[0] |= 0x00000004u; - return go_package_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return go_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_go_package() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.go_package) @@ -10483,7 +10463,7 @@ inline bool FileOptions::has_objc_class_prefix() const { return _internal_has_objc_class_prefix(); } inline void FileOptions::clear_objc_class_prefix() { - objc_class_prefix_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + objc_class_prefix_.ClearToEmpty(); _has_bits_[0] &= ~0x00000008u; } inline const std::string& FileOptions::objc_class_prefix() const { @@ -10503,31 +10483,30 @@ inline const std::string& FileOptions::_internal_objc_class_prefix() const { } inline void FileOptions::_internal_set_objc_class_prefix(const std::string& value) { _has_bits_[0] |= 0x00000008u; - objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_objc_class_prefix(std::string&& value) { _has_bits_[0] |= 0x00000008u; objc_class_prefix_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.objc_class_prefix) } inline void FileOptions::set_objc_class_prefix(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000008u; - objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix) } inline void FileOptions::set_objc_class_prefix(const char* value, size_t size) { _has_bits_[0] |= 0x00000008u; - objc_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + objc_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.objc_class_prefix) } inline std::string* FileOptions::_internal_mutable_objc_class_prefix() { _has_bits_[0] |= 0x00000008u; - return objc_class_prefix_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return objc_class_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_objc_class_prefix() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.objc_class_prefix) @@ -10557,7 +10536,7 @@ inline bool FileOptions::has_csharp_namespace() const { return _internal_has_csharp_namespace(); } inline void FileOptions::clear_csharp_namespace() { - csharp_namespace_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + csharp_namespace_.ClearToEmpty(); _has_bits_[0] &= ~0x00000010u; } inline const std::string& FileOptions::csharp_namespace() const { @@ -10577,31 +10556,30 @@ inline const std::string& FileOptions::_internal_csharp_namespace() const { } inline void FileOptions::_internal_set_csharp_namespace(const std::string& value) { _has_bits_[0] |= 0x00000010u; - csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_csharp_namespace(std::string&& value) { _has_bits_[0] |= 0x00000010u; csharp_namespace_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.csharp_namespace) } inline void FileOptions::set_csharp_namespace(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000010u; - csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace) } inline void FileOptions::set_csharp_namespace(const char* value, size_t size) { _has_bits_[0] |= 0x00000010u; - csharp_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + csharp_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace) } inline std::string* FileOptions::_internal_mutable_csharp_namespace() { _has_bits_[0] |= 0x00000010u; - return csharp_namespace_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return csharp_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_csharp_namespace() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.csharp_namespace) @@ -10631,7 +10609,7 @@ inline bool FileOptions::has_swift_prefix() const { return _internal_has_swift_prefix(); } inline void FileOptions::clear_swift_prefix() { - swift_prefix_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + swift_prefix_.ClearToEmpty(); _has_bits_[0] &= ~0x00000020u; } inline const std::string& FileOptions::swift_prefix() const { @@ -10651,31 +10629,30 @@ inline const std::string& FileOptions::_internal_swift_prefix() const { } inline void FileOptions::_internal_set_swift_prefix(const std::string& value) { _has_bits_[0] |= 0x00000020u; - swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_swift_prefix(std::string&& value) { _has_bits_[0] |= 0x00000020u; swift_prefix_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.swift_prefix) } inline void FileOptions::set_swift_prefix(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000020u; - swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.swift_prefix) } inline void FileOptions::set_swift_prefix(const char* value, size_t size) { _has_bits_[0] |= 0x00000020u; - swift_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + swift_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.swift_prefix) } inline std::string* FileOptions::_internal_mutable_swift_prefix() { _has_bits_[0] |= 0x00000020u; - return swift_prefix_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return swift_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_swift_prefix() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.swift_prefix) @@ -10705,7 +10682,7 @@ inline bool FileOptions::has_php_class_prefix() const { return _internal_has_php_class_prefix(); } inline void FileOptions::clear_php_class_prefix() { - php_class_prefix_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + php_class_prefix_.ClearToEmpty(); _has_bits_[0] &= ~0x00000040u; } inline const std::string& FileOptions::php_class_prefix() const { @@ -10725,31 +10702,30 @@ inline const std::string& FileOptions::_internal_php_class_prefix() const { } inline void FileOptions::_internal_set_php_class_prefix(const std::string& value) { _has_bits_[0] |= 0x00000040u; - php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_php_class_prefix(std::string&& value) { _has_bits_[0] |= 0x00000040u; php_class_prefix_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_class_prefix) } inline void FileOptions::set_php_class_prefix(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000040u; - php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix) } inline void FileOptions::set_php_class_prefix(const char* value, size_t size) { _has_bits_[0] |= 0x00000040u; - php_class_prefix_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + php_class_prefix_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_class_prefix) } inline std::string* FileOptions::_internal_mutable_php_class_prefix() { _has_bits_[0] |= 0x00000040u; - return php_class_prefix_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return php_class_prefix_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_php_class_prefix() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_class_prefix) @@ -10779,7 +10755,7 @@ inline bool FileOptions::has_php_namespace() const { return _internal_has_php_namespace(); } inline void FileOptions::clear_php_namespace() { - php_namespace_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + php_namespace_.ClearToEmpty(); _has_bits_[0] &= ~0x00000080u; } inline const std::string& FileOptions::php_namespace() const { @@ -10799,31 +10775,30 @@ inline const std::string& FileOptions::_internal_php_namespace() const { } inline void FileOptions::_internal_set_php_namespace(const std::string& value) { _has_bits_[0] |= 0x00000080u; - php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_php_namespace(std::string&& value) { _has_bits_[0] |= 0x00000080u; php_namespace_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_namespace) } inline void FileOptions::set_php_namespace(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000080u; - php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_namespace) } inline void FileOptions::set_php_namespace(const char* value, size_t size) { _has_bits_[0] |= 0x00000080u; - php_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + php_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_namespace) } inline std::string* FileOptions::_internal_mutable_php_namespace() { _has_bits_[0] |= 0x00000080u; - return php_namespace_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return php_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_php_namespace() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_namespace) @@ -10853,7 +10828,7 @@ inline bool FileOptions::has_php_metadata_namespace() const { return _internal_has_php_metadata_namespace(); } inline void FileOptions::clear_php_metadata_namespace() { - php_metadata_namespace_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + php_metadata_namespace_.ClearToEmpty(); _has_bits_[0] &= ~0x00000100u; } inline const std::string& FileOptions::php_metadata_namespace() const { @@ -10873,31 +10848,30 @@ inline const std::string& FileOptions::_internal_php_metadata_namespace() const } inline void FileOptions::_internal_set_php_metadata_namespace(const std::string& value) { _has_bits_[0] |= 0x00000100u; - php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_php_metadata_namespace(std::string&& value) { _has_bits_[0] |= 0x00000100u; php_metadata_namespace_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.php_metadata_namespace) } inline void FileOptions::set_php_metadata_namespace(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000100u; - php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_metadata_namespace) } inline void FileOptions::set_php_metadata_namespace(const char* value, size_t size) { _has_bits_[0] |= 0x00000100u; - php_metadata_namespace_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + php_metadata_namespace_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.php_metadata_namespace) } inline std::string* FileOptions::_internal_mutable_php_metadata_namespace() { _has_bits_[0] |= 0x00000100u; - return php_metadata_namespace_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return php_metadata_namespace_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_php_metadata_namespace() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.php_metadata_namespace) @@ -10927,7 +10901,7 @@ inline bool FileOptions::has_ruby_package() const { return _internal_has_ruby_package(); } inline void FileOptions::clear_ruby_package() { - ruby_package_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + ruby_package_.ClearToEmpty(); _has_bits_[0] &= ~0x00000200u; } inline const std::string& FileOptions::ruby_package() const { @@ -10947,31 +10921,30 @@ inline const std::string& FileOptions::_internal_ruby_package() const { } inline void FileOptions::_internal_set_ruby_package(const std::string& value) { _has_bits_[0] |= 0x00000200u; - ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void FileOptions::set_ruby_package(std::string&& value) { _has_bits_[0] |= 0x00000200u; ruby_package_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.FileOptions.ruby_package) } inline void FileOptions::set_ruby_package(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000200u; - ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.ruby_package) } inline void FileOptions::set_ruby_package(const char* value, size_t size) { _has_bits_[0] |= 0x00000200u; - ruby_package_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + ruby_package_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.ruby_package) } inline std::string* FileOptions::_internal_mutable_ruby_package() { _has_bits_[0] |= 0x00000200u; - return ruby_package_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return ruby_package_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* FileOptions::release_ruby_package() { // @@protoc_insertion_point(field_release:google.protobuf.FileOptions.ruby_package) @@ -11796,7 +11769,7 @@ inline bool UninterpretedOption_NamePart::has_name_part() const { return _internal_has_name_part(); } inline void UninterpretedOption_NamePart::clear_name_part() { - name_part_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_part_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& UninterpretedOption_NamePart::name_part() const { @@ -11816,31 +11789,30 @@ inline const std::string& UninterpretedOption_NamePart::_internal_name_part() co } inline void UninterpretedOption_NamePart::_internal_set_name_part(const std::string& value) { _has_bits_[0] |= 0x00000001u; - name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void UninterpretedOption_NamePart::set_name_part(std::string&& value) { _has_bits_[0] |= 0x00000001u; name_part_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.NamePart.name_part) } inline void UninterpretedOption_NamePart::set_name_part(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part) } inline void UninterpretedOption_NamePart::set_name_part(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - name_part_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_part_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.NamePart.name_part) } inline std::string* UninterpretedOption_NamePart::_internal_mutable_name_part() { _has_bits_[0] |= 0x00000001u; - return name_part_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_part_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* UninterpretedOption_NamePart::release_name_part() { // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.NamePart.name_part) @@ -11941,7 +11913,7 @@ inline bool UninterpretedOption::has_identifier_value() const { return _internal_has_identifier_value(); } inline void UninterpretedOption::clear_identifier_value() { - identifier_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + identifier_value_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& UninterpretedOption::identifier_value() const { @@ -11961,31 +11933,30 @@ inline const std::string& UninterpretedOption::_internal_identifier_value() cons } inline void UninterpretedOption::_internal_set_identifier_value(const std::string& value) { _has_bits_[0] |= 0x00000001u; - identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void UninterpretedOption::set_identifier_value(std::string&& value) { _has_bits_[0] |= 0x00000001u; identifier_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.identifier_value) } inline void UninterpretedOption::set_identifier_value(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value) } inline void UninterpretedOption::set_identifier_value(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - identifier_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + identifier_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.identifier_value) } inline std::string* UninterpretedOption::_internal_mutable_identifier_value() { _has_bits_[0] |= 0x00000001u; - return identifier_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return identifier_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* UninterpretedOption::release_identifier_value() { // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.identifier_value) @@ -12099,7 +12070,7 @@ inline bool UninterpretedOption::has_string_value() const { return _internal_has_string_value(); } inline void UninterpretedOption::clear_string_value() { - string_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + string_value_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& UninterpretedOption::string_value() const { @@ -12119,31 +12090,30 @@ inline const std::string& UninterpretedOption::_internal_string_value() const { } inline void UninterpretedOption::_internal_set_string_value(const std::string& value) { _has_bits_[0] |= 0x00000002u; - string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void UninterpretedOption::set_string_value(std::string&& value) { _has_bits_[0] |= 0x00000002u; string_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.string_value) } inline void UninterpretedOption::set_string_value(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value) } inline void UninterpretedOption::set_string_value(const void* value, size_t size) { _has_bits_[0] |= 0x00000002u; - string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.string_value) } inline std::string* UninterpretedOption::_internal_mutable_string_value() { _has_bits_[0] |= 0x00000002u; - return string_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return string_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* UninterpretedOption::release_string_value() { // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.string_value) @@ -12173,7 +12143,7 @@ inline bool UninterpretedOption::has_aggregate_value() const { return _internal_has_aggregate_value(); } inline void UninterpretedOption::clear_aggregate_value() { - aggregate_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + aggregate_value_.ClearToEmpty(); _has_bits_[0] &= ~0x00000004u; } inline const std::string& UninterpretedOption::aggregate_value() const { @@ -12193,31 +12163,30 @@ inline const std::string& UninterpretedOption::_internal_aggregate_value() const } inline void UninterpretedOption::_internal_set_aggregate_value(const std::string& value) { _has_bits_[0] |= 0x00000004u; - aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void UninterpretedOption::set_aggregate_value(std::string&& value) { _has_bits_[0] |= 0x00000004u; aggregate_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.UninterpretedOption.aggregate_value) } inline void UninterpretedOption::set_aggregate_value(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000004u; - aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value) } inline void UninterpretedOption::set_aggregate_value(const char* value, size_t size) { _has_bits_[0] |= 0x00000004u; - aggregate_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + aggregate_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.UninterpretedOption.aggregate_value) } inline std::string* UninterpretedOption::_internal_mutable_aggregate_value() { _has_bits_[0] |= 0x00000004u; - return aggregate_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return aggregate_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* UninterpretedOption::release_aggregate_value() { // @@protoc_insertion_point(field_release:google.protobuf.UninterpretedOption.aggregate_value) @@ -12345,7 +12314,7 @@ inline bool SourceCodeInfo_Location::has_leading_comments() const { return _internal_has_leading_comments(); } inline void SourceCodeInfo_Location::clear_leading_comments() { - leading_comments_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + leading_comments_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& SourceCodeInfo_Location::leading_comments() const { @@ -12365,31 +12334,30 @@ inline const std::string& SourceCodeInfo_Location::_internal_leading_comments() } inline void SourceCodeInfo_Location::_internal_set_leading_comments(const std::string& value) { _has_bits_[0] |= 0x00000001u; - leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void SourceCodeInfo_Location::set_leading_comments(std::string&& value) { _has_bits_[0] |= 0x00000001u; leading_comments_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.SourceCodeInfo.Location.leading_comments) } inline void SourceCodeInfo_Location::set_leading_comments(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments) } inline void SourceCodeInfo_Location::set_leading_comments(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - leading_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + leading_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.leading_comments) } inline std::string* SourceCodeInfo_Location::_internal_mutable_leading_comments() { _has_bits_[0] |= 0x00000001u; - return leading_comments_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return leading_comments_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* SourceCodeInfo_Location::release_leading_comments() { // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.leading_comments) @@ -12419,7 +12387,7 @@ inline bool SourceCodeInfo_Location::has_trailing_comments() const { return _internal_has_trailing_comments(); } inline void SourceCodeInfo_Location::clear_trailing_comments() { - trailing_comments_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + trailing_comments_.ClearToEmpty(); _has_bits_[0] &= ~0x00000002u; } inline const std::string& SourceCodeInfo_Location::trailing_comments() const { @@ -12439,31 +12407,30 @@ inline const std::string& SourceCodeInfo_Location::_internal_trailing_comments() } inline void SourceCodeInfo_Location::_internal_set_trailing_comments(const std::string& value) { _has_bits_[0] |= 0x00000002u; - trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void SourceCodeInfo_Location::set_trailing_comments(std::string&& value) { _has_bits_[0] |= 0x00000002u; trailing_comments_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.SourceCodeInfo.Location.trailing_comments) } inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000002u; - trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments) } inline void SourceCodeInfo_Location::set_trailing_comments(const char* value, size_t size) { _has_bits_[0] |= 0x00000002u; - trailing_comments_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + trailing_comments_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceCodeInfo.Location.trailing_comments) } inline std::string* SourceCodeInfo_Location::_internal_mutable_trailing_comments() { _has_bits_[0] |= 0x00000002u; - return trailing_comments_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return trailing_comments_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* SourceCodeInfo_Location::release_trailing_comments() { // @@protoc_insertion_point(field_release:google.protobuf.SourceCodeInfo.Location.trailing_comments) @@ -12661,7 +12628,7 @@ inline bool GeneratedCodeInfo_Annotation::has_source_file() const { return _internal_has_source_file(); } inline void GeneratedCodeInfo_Annotation::clear_source_file() { - source_file_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + source_file_.ClearToEmpty(); _has_bits_[0] &= ~0x00000001u; } inline const std::string& GeneratedCodeInfo_Annotation::source_file() const { @@ -12681,31 +12648,30 @@ inline const std::string& GeneratedCodeInfo_Annotation::_internal_source_file() } inline void GeneratedCodeInfo_Annotation::_internal_set_source_file(const std::string& value) { _has_bits_[0] |= 0x00000001u; - source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void GeneratedCodeInfo_Annotation::set_source_file(std::string&& value) { _has_bits_[0] |= 0x00000001u; source_file_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.GeneratedCodeInfo.Annotation.source_file) } inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value) { GOOGLE_DCHECK(value != nullptr); _has_bits_[0] |= 0x00000001u; - source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file) } inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value, size_t size) { _has_bits_[0] |= 0x00000001u; - source_file_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + source_file_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.GeneratedCodeInfo.Annotation.source_file) } inline std::string* GeneratedCodeInfo_Annotation::_internal_mutable_source_file() { _has_bits_[0] |= 0x00000001u; - return source_file_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return source_file_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* GeneratedCodeInfo_Annotation::release_source_file() { // @@protoc_insertion_point(field_release:google.protobuf.GeneratedCodeInfo.Annotation.source_file) diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index a332dab037..2707ed4b58 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -37,7 +37,6 @@ #include #include -#include #include #include diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h index 10e60fc535..5fb593efc6 100644 --- a/src/google/protobuf/descriptor_database.h +++ b/src/google/protobuf/descriptor_database.h @@ -187,9 +187,6 @@ class PROTOBUF_EXPORT SimpleDescriptorDatabase : public DescriptorDatabase { bool FindAllFileNames(std::vector* output) override; private: - // So that it can use DescriptorIndex. - friend class EncodedDescriptorDatabase; - // An index mapping file names, symbol names, and extension numbers to // some sort of values. template diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 8a9f7f0b5c..8f4434b834 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index 3d9adc200b..e57d27f51a 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -432,15 +432,10 @@ void DynamicMessage::SharedCtor(bool lock_factory) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: if (!field->is_repeated()) { - const std::string* default_value; - if (is_prototype()) { - default_value = &field->default_value_string(); - } else { - default_value = &(reinterpret_cast( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])) - ->Get()); - } + const std::string* default_value = + field->default_value_string().empty() + ? &internal::GetEmptyStringAlreadyInited() + : nullptr; ArenaStringPtr* asp = new (field_ptr) ArenaStringPtr(); asp->UnsafeSetDefault(default_value); } else { @@ -523,10 +518,10 @@ DynamicMessage::~DynamicMessage() { default: case FieldOptions::STRING: { const std::string* default_value = - &(reinterpret_cast( - reinterpret_cast(type_info_->prototype) + - type_info_->offsets[i]) - ->Get()); + reinterpret_cast( + reinterpret_cast(type_info_->prototype) + + type_info_->offsets[i]) + ->GetPointer(); reinterpret_cast(field_ptr)->Destroy( default_value, NULL); break; @@ -583,10 +578,10 @@ DynamicMessage::~DynamicMessage() { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { const std::string* default_value = - &(reinterpret_cast( - type_info_->prototype->OffsetToPointer( - type_info_->offsets[i])) - ->Get()); + reinterpret_cast( + type_info_->prototype->OffsetToPointer( + type_info_->offsets[i])) + ->GetPointer(); reinterpret_cast(field_ptr)->Destroy(default_value, NULL); break; diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index 5e6f0f9364..f1e5e9207f 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index 443785bffe..d74276776b 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index b854155ab9..3ff9315277 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -62,7 +61,6 @@ using google::protobuf::internal::DescriptorTable; using google::protobuf::internal::ExtensionSet; using google::protobuf::internal::GenericTypeHandler; using google::protobuf::internal::GetEmptyString; -using google::protobuf::internal::InlinedStringField; using google::protobuf::internal::InternalMetadata; using google::protobuf::internal::LazyField; using google::protobuf::internal::MapFieldBase; @@ -313,15 +311,8 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - const std::string* ptr = - &GetField(message, field).GetNoArena(); - total_size += StringSpaceUsedExcludingSelfLong(*ptr); - break; - } - const std::string* ptr = - &GetField(message, field).Get(); + GetField(message, field).GetPointer(); // Initially, the string points to the default value stored // in the prototype. Only count the string if it has been @@ -329,7 +320,7 @@ size_t Reflection::SpaceUsedLong(const Message& message) const { // Except oneof fields, those never point to a default instance, // and there is no default instance to point to. if (schema_.InRealOneof(field) || - ptr != &DefaultRaw(field).Get()) { + ptr != DefaultRaw(field).GetPointer()) { // string fields are represented by just a pointer, so also // include sizeof(string) as well. total_size += @@ -450,27 +441,27 @@ void Reflection::SwapField(Message* message1, Message* message2, Arena* arena1 = GetArena(message1); Arena* arena2 = GetArena(message2); - if (IsInlined(field)) { - InlinedStringField* string1 = - MutableRaw(message1, field); - InlinedStringField* string2 = - MutableRaw(message2, field); - string1->Swap(string2); - break; - } - ArenaStringPtr* string1 = MutableRaw(message1, field); ArenaStringPtr* string2 = MutableRaw(message2, field); const std::string* default_ptr = - &DefaultRaw(field).Get(); + DefaultRaw(field).GetPointer(); if (arena1 == arena2) { string1->Swap(string2, default_ptr, arena1); + } else if (string1->IsDefault(default_ptr) && + string2->IsDefault(default_ptr)) { + // Nothing to do. + } else if (string1->IsDefault(default_ptr)) { + string1->Set(default_ptr, string2->Get(), arena1); + string2->UnsafeSetDefault(default_ptr); + } else if (string2->IsDefault(default_ptr)) { + string2->Set(default_ptr, string1->Get(), arena2); + string1->UnsafeSetDefault(default_ptr); } else { - const std::string temp = string1->Get(); + std::string temp = string1->Get(); string1->Set(default_ptr, string2->Get(), arena1); - string2->Set(default_ptr, temp, arena2); + string2->Set(default_ptr, std::move(temp), arena2); } } break; } @@ -834,16 +825,8 @@ void Reflection::ClearField(Message* message, switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - const std::string* default_ptr = - &DefaultRaw(field).GetNoArena(); - MutableRaw(message, field) - ->SetNoArena(default_ptr, *default_ptr); - break; - } - const std::string* default_ptr = - &DefaultRaw(field).Get(); + DefaultRaw(field).GetPointer(); MutableRaw(message, field) ->SetAllocated(default_ptr, nullptr, GetArena(message)); break; @@ -1197,11 +1180,11 @@ std::string Reflection::GetString(const Message& message, switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - return GetField(message, field).GetNoArena(); + if (auto* value = + GetField(message, field).GetPointer()) { + return *value; } - - return GetField(message, field).Get(); + return field->default_value_string(); } } } @@ -1221,11 +1204,11 @@ const std::string& Reflection::GetStringReference(const Message& message, switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - return GetField(message, field).GetNoArena(); + if (auto* value = + GetField(message, field).GetPointer()) { + return *value; } - - return GetField(message, field).Get(); + return field->default_value_string(); } } } @@ -1242,20 +1225,14 @@ void Reflection::SetString(Message* message, const FieldDescriptor* field, switch (field->options().ctype()) { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: { - if (IsInlined(field)) { - MutableField(message, field) - ->SetNoArena(nullptr, std::move(value)); - break; - } - // Oneof string fields are never set as a default instance. // We just need to pass some arbitrary default string to make it work. // This allows us to not have the real default accessible from // reflection. const std::string* default_ptr = schema_.InRealOneof(field) - ? &GetEmptyString() - : &DefaultRaw(field).Get(); + ? nullptr + : DefaultRaw(field).GetPointer(); if (schema_.InRealOneof(field) && !HasOneofField(*message, field)) { ClearOneof(message, field->containing_oneof()); MutableField(message, field) @@ -1968,10 +1945,6 @@ const Type& Reflection::GetRaw(const Message& message, return GetConstRefAtOffset(message, schema_.GetFieldOffset(field)); } -bool Reflection::IsInlined(const FieldDescriptor* field) const { - return schema_.IsFieldInlined(field); -} - template Type* Reflection::MutableRaw(Message* message, const FieldDescriptor* field) const { @@ -2058,11 +2031,6 @@ bool Reflection::HasBit(const Message& message, case FieldDescriptor::CPPTYPE_STRING: switch (field->options().ctype()) { default: { - if (IsInlined(field)) { - return !GetField(message, field) - .GetNoArena() - .empty(); - } return GetField(message, field).Get().size() > 0; } } @@ -2175,9 +2143,8 @@ void Reflection::ClearOneof(Message* message, // We just need to pass some arbitrary default string to make it // work. This allows us to not have the real default accessible // from reflection. - const std::string* default_ptr = &GetEmptyString(); MutableField(message, field) - ->Destroy(default_ptr, GetArena(message)); + ->Destroy(nullptr, GetArena(message)); break; } } diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 1c284959d0..12abb4f97f 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -42,8 +42,6 @@ #include #include #include -// TODO(jasonh): Remove this once the compiler change to directly include this -// is released to components. #include #include #include @@ -59,7 +57,6 @@ namespace google { namespace protobuf { -class DescriptorPool; class MapKey; class MapValueRef; class MessageLayoutInspector; @@ -148,17 +145,6 @@ struct ReflectionSchema { } } - bool IsFieldInlined(const FieldDescriptor* field) const { - if (InRealOneof(field)) { - size_t offset = - static_cast(field->containing_type()->field_count() + - field->containing_oneof()->index()); - return Inlined(offsets_[offset], field->type()); - } else { - return Inlined(offsets_[field->index()], field->type()); - } - } - uint32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const { return static_cast(oneof_case_offset_) + static_cast(static_cast(oneof_descriptor->index()) * @@ -215,14 +201,17 @@ struct ReflectionSchema { // Returns true if the field's accessor is called by any external code (aka, // non proto library code). bool IsFieldUsed(const FieldDescriptor* field) const { + (void)field; return true; } bool IsFieldStripped(const FieldDescriptor* field) const { + (void)field; return false; } bool IsMessageStripped(const Descriptor* descriptor) const { + (void)descriptor; return false; } @@ -246,25 +235,9 @@ struct ReflectionSchema { int weak_field_map_offset_; // We tag offset values to provide additional data about fields (such as - // inlined). + // "unused"). static uint32 OffsetValue(uint32 v, FieldDescriptor::Type type) { - v &= 0x7FFFFFFFu; - if (type == FieldDescriptor::TYPE_STRING || - type == FieldDescriptor::TYPE_BYTES) { - return v & ~1u; - } else { - return v; - } - } - - static bool Inlined(uint32 v, FieldDescriptor::Type type) { - if (type == FieldDescriptor::TYPE_STRING || - type == FieldDescriptor::TYPE_BYTES) { - return v & 1u; - } else { - // Non string/byte fields are not inlined. - return false; - } + return v & 0x7FFFFFFFu; } }; diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h index 9ff58e0454..731d6c5212 100644 --- a/src/google/protobuf/generated_message_table_driven.h +++ b/src/google/protobuf/generated_message_table_driven.h @@ -73,9 +73,7 @@ enum ProcessingTypes { TYPE_STRING_STRING_PIECE = 20, TYPE_BYTES_CORD = 21, TYPE_BYTES_STRING_PIECE = 22, - TYPE_STRING_INLINED = 23, - TYPE_BYTES_INLINED = 24, - TYPE_MAP = 25, + TYPE_MAP = 23, }; static_assert(TYPE_MAP < kRepeatedMask, "Invalid enum"); @@ -106,8 +104,7 @@ struct PROTOBUF_EXPORT FieldMetadata { enum { kCordType = 19, kStringPieceType = 20, - kInlinedType = 21, - kNumTypes = 21, + kNumTypes = 20, kSpecial = kNumTypes * kNumTypeClasses, }; diff --git a/src/google/protobuf/generated_message_table_driven_lite.h b/src/google/protobuf/generated_message_table_driven_lite.h index 7405c3dc31..3c65acdfe8 100644 --- a/src/google/protobuf/generated_message_table_driven_lite.h +++ b/src/google/protobuf/generated_message_table_driven_lite.h @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -50,7 +49,6 @@ namespace internal { enum StringType { StringType_STRING = 0, - StringType_INLINED = 3 }; // Logically a superset of StringType, consisting of all field types that @@ -59,8 +57,7 @@ enum ProcessingType { ProcessingType_STRING = 0, ProcessingType_CORD = 1, ProcessingType_STRING_PIECE = 2, - ProcessingType_INLINED = 3, - ProcessingType_MESSAGE = 4, + ProcessingType_MESSAGE = 3, }; enum Cardinality { @@ -90,8 +87,7 @@ inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) { template inline Type* AddField(MessageLite* msg, int64 offset) { - static_assert(std::is_pod::value || - std::is_same::value, + static_assert(std::is_pod::value, "Do not assign"); RepeatedField* repeated = Raw>(msg, offset); @@ -157,12 +153,7 @@ inline void ClearOneofField(const ParseTableField& field, Arena* arena, case WireFormatLite::TYPE_STRING: case WireFormatLite::TYPE_BYTES: Raw(msg, field.offset) - ->Destroy(&GetEmptyStringAlreadyInited(), arena); - break; - - case TYPE_STRING_INLINED: - case TYPE_BYTES_INLINED: - Raw(msg, field.offset)->DestroyNoArena(NULL); + ->Destroy(ArenaStringPtr::EmptyDefault{}, arena); break; default: @@ -197,10 +188,6 @@ inline void ResetOneofField(const ParseTable& table, int field_number, Raw(msg, offset) ->UnsafeSetDefault(static_cast(default_ptr)); break; - case ProcessingType_INLINED: - new (Raw(msg, offset)) - InlinedStringField(*static_cast(default_ptr)); - break; case ProcessingType_MESSAGE: MessageLite** submessage = Raw(msg, offset); const MessageLite* prototype = @@ -225,35 +212,12 @@ static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, #endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED switch (ctype) { - case StringType_INLINED: { - InlinedStringField* s = nullptr; - switch (cardinality) { - case Cardinality_SINGULAR: - // TODO(ckennelly): Is this optimal? - s = MutableField(msg, has_bits, has_bit_index, - offset); - break; - case Cardinality_REPEATED: - s = AddField(msg, offset); - break; - case Cardinality_ONEOF: - s = Raw(msg, offset); - break; - } - GOOGLE_DCHECK(s != nullptr); - std::string* value = s->MutableNoArena(NULL); - if (PROTOBUF_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) { - return false; - } - utf8_string_data = *value; - break; - } case StringType_STRING: { switch (cardinality) { case Cardinality_SINGULAR: { ArenaStringPtr* field = MutableField( msg, has_bits, has_bit_index, offset); - std::string* value = field->Mutable( + std::string* value = field->MutableNoCopy( static_cast(default_ptr), arena); if (PROTOBUF_PREDICT_FALSE( !WireFormatLite::ReadString(input, value))) { @@ -271,7 +235,7 @@ static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, } break; case Cardinality_ONEOF: { ArenaStringPtr* field = Raw(msg, offset); - std::string* value = field->Mutable( + std::string* value = field->MutableNoCopy( static_cast(default_ptr), arena); if (PROTOBUF_PREDICT_FALSE( !WireFormatLite::ReadString(input, value))) { @@ -481,23 +445,6 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, } break; } - case TYPE_BYTES_INLINED: -#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - case TYPE_STRING_INLINED: -#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - { - Arena* const arena = msg->GetArena(); - const void* default_ptr = table.aux[field_number].strings.default_ptr; - - if (PROTOBUF_PREDICT_FALSE( - (!HandleString( - input, msg, arena, has_bits, presence_index, offset, - default_ptr, nullptr)))) { - return false; - } - break; - } case WireFormatLite::TYPE_BYTES | kOneofMask: #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case WireFormatLite::TYPE_STRING | kOneofMask: @@ -521,10 +468,8 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, break; } case (WireFormatLite::TYPE_BYTES) | kRepeatedMask: - case TYPE_BYTES_INLINED | kRepeatedMask: #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case (WireFormatLite::TYPE_STRING) | kRepeatedMask: - case TYPE_STRING_INLINED | kRepeatedMask: #endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED { Arena* const arena = msg->GetArena(); @@ -554,7 +499,6 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, } break; } - case TYPE_STRING_INLINED | kRepeatedMask: case (WireFormatLite::TYPE_STRING) | kRepeatedMask: { Arena* const arena = msg->GetArena(); const void* default_ptr = table.aux[field_number].strings.default_ptr; @@ -712,22 +656,6 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, break; } -#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED - case TYPE_STRING_INLINED: { - Arena* const arena = msg->GetArena(); - const void* default_ptr = table.aux[field_number].strings.default_ptr; - const char* field_name = table.aux[field_number].strings.field_name; - - if (PROTOBUF_PREDICT_FALSE( - (!HandleString( - input, msg, arena, has_bits, presence_index, offset, - default_ptr, field_name)))) { - return false; - } - break; - } -#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED case TYPE_MAP: { if (PROTOBUF_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)( input, Raw(msg, offset)))) { @@ -750,8 +678,6 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, GOOGLE_DCHECK_NE(processing_type, kRepeatedMask); GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask); - GOOGLE_DCHECK_NE(TYPE_BYTES_INLINED | kRepeatedMask, processing_type); - GOOGLE_DCHECK_NE(TYPE_STRING_INLINED | kRepeatedMask, processing_type); // Mask out kRepeatedMask bit, allowing the jump table to be smaller. switch (static_cast(processing_type ^ @@ -847,7 +773,7 @@ bool MergePartialFromCodedStreamInlined(MessageLite* msg, } } } -} +} // NOLINT(readability/fn_size) template bool MergePartialFromCodedStreamImpl(MessageLite* msg, const ParseTable& table, diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index 01f65ae9eb..aaeadc78ca 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -246,10 +246,6 @@ struct PrimitiveTypeHelper : PrimitiveTypeHelper {}; -template <> -struct PrimitiveTypeHelper - : PrimitiveTypeHelper {}; - // We want to serialize to both CodedOutputStream and directly into byte arrays // without duplicating the code. In fact we might want extra output channels in // the future. @@ -408,15 +404,6 @@ struct SingularFieldHelper { } }; -template <> -struct SingularFieldHelper { - template - static void Serialize(const void* field, const FieldMetadata& md, O* output) { - WriteTagTo(md.tag, output); - SerializeTo(&Get(field), output); - } -}; - template struct RepeatedFieldHelper { template @@ -489,10 +476,6 @@ struct RepeatedFieldHelper { }; -template <> -struct RepeatedFieldHelper - : RepeatedFieldHelper {}; - template struct PackedFieldHelper { template @@ -528,9 +511,6 @@ struct PackedFieldHelper template <> struct PackedFieldHelper : PackedFieldHelper {}; -template <> -struct PackedFieldHelper - : PackedFieldHelper {}; template struct OneOfFieldHelper { @@ -541,15 +521,6 @@ struct OneOfFieldHelper { }; -template <> -struct OneOfFieldHelper { - template - static void Serialize(const void* field, const FieldMetadata& md, O* output) { - SingularFieldHelper::Serialize( - Get(field), md, output); - } -}; - void SerializeNotImplemented(int field) { GOOGLE_LOG(FATAL) << "Not implemented field number " << field; } @@ -590,11 +561,6 @@ bool IsNull(const void* ptr) { } -template <> -bool IsNull(const void* ptr) { - return static_cast(ptr)->empty(); -} - #define SERIALIZERS_FOR_TYPE(type) \ case SERIALIZE_TABLE_OP(type, FieldMetadata::kPresence): \ if (!IsPresent(base, field_metadata.has_offset)) continue; \ @@ -642,7 +608,6 @@ void SerializeInternal(const uint8* base, SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); - SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType); // Special cases case FieldMetadata::kSpecial: @@ -687,7 +652,6 @@ uint8* SerializeInternalToArray(const uint8* base, SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SFIXED64); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT32); SERIALIZERS_FOR_TYPE(WireFormatLite::TYPE_SINT64); - SERIALIZERS_FOR_TYPE(FieldMetadata::kInlinedType); // Special cases case FieldMetadata::kSpecial: { io::ArrayOutputStream array_stream(array_output.ptr, INT_MAX); diff --git a/src/google/protobuf/inlined_string_field.h b/src/google/protobuf/inlined_string_field.h deleted file mode 100644 index 991c0e1f3f..0000000000 --- a/src/google/protobuf/inlined_string_field.h +++ /dev/null @@ -1,260 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ -#define GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ - -#include -#include - -#include -#include - -// Must be included last. -#include - -#ifdef SWIG -#error "You cannot SWIG proto headers" -#endif - -namespace google { -namespace protobuf { - -class Arena; - -namespace internal { - -// InlinedStringField wraps a std::string instance and exposes an API similar to -// ArenaStringPtr's wrapping of a std::string* instance. As std::string is -// never allocated on the Arena, we expose only the *NoArena methods of -// ArenaStringPtr. -// -// default_value parameters are taken for consistency with ArenaStringPtr, but -// are not used for most methods. With inlining, these should be removed from -// the generated binary. -class PROTOBUF_EXPORT InlinedStringField { - public: - InlinedStringField() PROTOBUF_ALWAYS_INLINE; - explicit InlinedStringField(const std::string& default_value); - - void AssignWithDefault(const std::string* default_value, - const InlinedStringField& from) PROTOBUF_ALWAYS_INLINE; - - void ClearToEmpty(const std::string* default_value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - ClearToEmptyNoArena(default_value); - } - void ClearNonDefaultToEmpty() PROTOBUF_ALWAYS_INLINE { - ClearNonDefaultToEmptyNoArena(); - } - void ClearToEmptyNoArena(const std::string* /*default_value*/) - PROTOBUF_ALWAYS_INLINE { - ClearNonDefaultToEmptyNoArena(); - } - void ClearNonDefaultToEmptyNoArena() PROTOBUF_ALWAYS_INLINE; - - void ClearToDefault(const std::string* default_value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - ClearToDefaultNoArena(default_value); - } - void ClearToDefaultNoArena(const std::string* default_value) - PROTOBUF_ALWAYS_INLINE; - - void Destroy(const std::string* default_value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - DestroyNoArena(default_value); - } - void DestroyNoArena(const std::string* default_value) PROTOBUF_ALWAYS_INLINE; - - const std::string& Get() const PROTOBUF_ALWAYS_INLINE { return GetNoArena(); } - const std::string& GetNoArena() const PROTOBUF_ALWAYS_INLINE; - - std::string* Mutable(const std::string* default_value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - return MutableNoArena(default_value); - } - std::string* MutableNoArena(const std::string* default_value) - PROTOBUF_ALWAYS_INLINE; - - std::string* Release(const std::string* default_value, Arena* /*arena*/) { - return ReleaseNoArena(default_value); - } - std::string* ReleaseNonDefault(const std::string* default_value, - Arena* /*arena*/) { - return ReleaseNonDefaultNoArena(default_value); - } - std::string* ReleaseNoArena(const std::string* default_value) { - return ReleaseNonDefaultNoArena(default_value); - } - std::string* ReleaseNonDefaultNoArena(const std::string* default_value); - - void Set(const std::string* default_value, StringPiece value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - SetNoArena(default_value, value); - } - void SetLite(const std::string* default_value, StringPiece value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - SetNoArena(default_value, value); - } - void SetNoArena(const std::string* default_value, - StringPiece value) PROTOBUF_ALWAYS_INLINE; - - void Set(const std::string* default_value, const std::string& value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - SetNoArena(default_value, value); - } - void SetLite(const std::string* default_value, const std::string& value, - Arena* /*arena*/) PROTOBUF_ALWAYS_INLINE { - SetNoArena(default_value, value); - } - void SetNoArena(const std::string* default_value, - const std::string& value) PROTOBUF_ALWAYS_INLINE; - - void SetNoArena(const std::string* default_value, - std::string&& value) PROTOBUF_ALWAYS_INLINE; - void SetAllocated(const std::string* default_value, std::string* value, - Arena* /*arena*/) { - SetAllocatedNoArena(default_value, value); - } - void SetAllocatedNoArena(const std::string* default_value, - std::string* value); - void Swap(InlinedStringField* from) PROTOBUF_ALWAYS_INLINE; - std::string* UnsafeMutablePointer(); - void UnsafeSetDefault(const std::string* default_value); - std::string* UnsafeArenaRelease(const std::string* default_value, - Arena* arena); - void UnsafeArenaSetAllocated(const std::string* default_value, - std::string* value, Arena* arena); - - bool IsDefault(const std::string* /*default_value*/) { return false; } - - private: - std::string value_; -}; - -inline InlinedStringField::InlinedStringField() {} - -inline InlinedStringField::InlinedStringField(const std::string& default_value) - : value_(default_value) {} - -inline void InlinedStringField::AssignWithDefault( - const std::string* /*default_value*/, const InlinedStringField& from) { - value_ = from.value_; -} - -inline const std::string& InlinedStringField::GetNoArena() const { - return value_; -} - -inline std::string* InlinedStringField::MutableNoArena(const std::string*) { - return &value_; -} - -inline void InlinedStringField::SetAllocatedNoArena( - const std::string* default_value, std::string* value) { - if (value == NULL) { - value_.assign(*default_value); - } else { - value_.assign(std::move(*value)); - delete value; - } -} - -inline void InlinedStringField::DestroyNoArena(const std::string*) { - // This is invoked from the generated message's ArenaDtor, which is used to - // clean up objects not allocated on the Arena. - this->~InlinedStringField(); -} - -inline void InlinedStringField::ClearNonDefaultToEmptyNoArena() { - value_.clear(); -} - -inline void InlinedStringField::ClearToDefaultNoArena( - const std::string* default_value) { - value_.assign(*default_value); -} - -inline std::string* InlinedStringField::ReleaseNonDefaultNoArena( - const std::string* default_value) { - std::string* released = new std::string(*default_value); - value_.swap(*released); - return released; -} - -inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/, - StringPiece value) { - value_.assign(value.data(), value.length()); -} - -inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/, - const std::string& value) { - value_.assign(value); -} - -inline void InlinedStringField::SetNoArena(const std::string* /*default_value*/, - std::string&& value) { - value_.assign(std::move(value)); -} - -inline void InlinedStringField::Swap(InlinedStringField* from) { - value_.swap(from->value_); -} - -inline std::string* InlinedStringField::UnsafeMutablePointer() { - return &value_; -} - -inline void InlinedStringField::UnsafeSetDefault( - const std::string* default_value) { - value_.assign(*default_value); -} - -inline std::string* InlinedStringField::UnsafeArenaRelease( - const std::string* default_value, Arena* /*arena*/) { - return ReleaseNoArena(default_value); -} - -inline void InlinedStringField::UnsafeArenaSetAllocated( - const std::string* default_value, std::string* value, Arena* /*arena*/) { - if (value == NULL) { - value_.assign(*default_value); - } else { - value_.assign(*value); - } -} - -} // namespace internal -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_INLINED_STRING_FIELD_H__ diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc index 4b1bf802e0..52617e9efe 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl.cc @@ -165,25 +165,14 @@ int FileInputStream::CopyingFileInputStream::Skip(int count) { // =================================================================== FileOutputStream::FileOutputStream(int file_descriptor, int block_size) - : copying_output_(file_descriptor), impl_(©ing_output_, block_size) {} - -FileOutputStream::~FileOutputStream() { impl_.Flush(); } + : CopyingOutputStreamAdaptor(©ing_output_), + copying_output_(file_descriptor) {} bool FileOutputStream::Close() { - bool flush_succeeded = impl_.Flush(); + bool flush_succeeded = Flush(); return copying_output_.Close() && flush_succeeded; } -bool FileOutputStream::Flush() { return impl_.Flush(); } - -bool FileOutputStream::Next(void** data, int* size) { - return impl_.Next(data, size); -} - -void FileOutputStream::BackUp(int count) { impl_.BackUp(count); } - -int64_t FileOutputStream::ByteCount() const { return impl_.ByteCount(); } - FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( int file_descriptor) : file_(file_descriptor), @@ -191,6 +180,8 @@ FileOutputStream::CopyingFileOutputStream::CopyingFileOutputStream( is_closed_(false), errno_(0) {} +FileOutputStream::~FileOutputStream() { Flush(); } + FileOutputStream::CopyingFileOutputStream::~CopyingFileOutputStream() { if (close_on_delete_) { if (!Close()) { diff --git a/src/google/protobuf/io/zero_copy_stream_impl.h b/src/google/protobuf/io/zero_copy_stream_impl.h index 6e5cdebbf1..0206e3887e 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.h +++ b/src/google/protobuf/io/zero_copy_stream_impl.h @@ -139,13 +139,14 @@ class PROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { // harming performance. Also, it's conceivable that FileOutputStream could // someday be enhanced to use zero-copy file descriptors on OSs which // support them. -class PROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { +class PROTOBUF_EXPORT FileOutputStream : public CopyingOutputStreamAdaptor { public: // Creates a stream that writes to the given Unix file descriptor. // If a block_size is given, it specifies the size of the buffers // that should be returned by Next(). Otherwise, a reasonable default // is used. explicit FileOutputStream(int file_descriptor, int block_size = -1); + ~FileOutputStream() override; // Flushes any buffers and closes the underlying file. Returns false if @@ -153,11 +154,6 @@ class PROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { // Even if an error occurs, the file descriptor is closed when this returns. bool Close(); - // Flushes FileOutputStream's buffers but does not close the - // underlying file. No special measures are taken to ensure that - // underlying operating system file object is synchronized to disk. - bool Flush(); - // By default, the file descriptor is not closed when the stream is // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: // This leaves no way for the caller to detect if close() fails. If @@ -171,11 +167,6 @@ class PROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { // fail. int GetErrno() const { return copying_output_.GetErrno(); } - // implements ZeroCopyOutputStream --------------------------------- - bool Next(void** data, int* size) override; - void BackUp(int count) override; - int64_t ByteCount() const override; - private: class PROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { public: @@ -202,7 +193,6 @@ class PROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { }; CopyingFileOutputStream copying_output_; - CopyingOutputStreamAdaptor impl_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream); }; diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc index 34bf45ff70..54c5db945e 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc @@ -342,6 +342,37 @@ int64_t CopyingOutputStreamAdaptor::ByteCount() const { return position_ + buffer_used_; } +bool CopyingOutputStreamAdaptor::WriteAliasedRaw(const void* data, int size) { + if (size >= buffer_size_) { + if (!Flush() || !copying_stream_->Write(data, size)) { + return false; + } + GOOGLE_DCHECK_EQ(buffer_used_, 0); + position_ += size; + return true; + } + + void* out; + int out_size; + while (true) { + if (!Next(&out, &out_size)) { + return false; + } + + if (size <= out_size) { + std::memcpy(out, data, size); + BackUp(out_size - size); + return true; + } + + std::memcpy(out, data, out_size); + data = static_cast(data) + out_size; + size -= out_size; + } + return true; +} + + bool CopyingOutputStreamAdaptor::WriteBuffer() { if (failed_) { // Already failed on a previous write. diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h index 2f0c662274..cfe81d2cc1 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h +++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h @@ -307,6 +307,8 @@ class PROTOBUF_EXPORT CopyingOutputStreamAdaptor : public ZeroCopyOutputStream { bool Next(void** data, int* size) override; void BackUp(int count) override; int64_t ByteCount() const override; + bool WriteAliasedRaw(const void* data, int size) override; + bool AllowsAliasing() const override { return true; } private: // Write the current buffer, if it is present. diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc index ea18a20883..deb5f06b83 100644 --- a/src/google/protobuf/lite_unittest.cc +++ b/src/google/protobuf/lite_unittest.cc @@ -41,6 +41,8 @@ #include #include #include +#include +#include #include #include #include @@ -1187,5 +1189,84 @@ TEST(Lite, AliasedEnum) { EXPECT_EQ(protobuf_unittest::DupEnum::FOO2, value); } + +TEST(Lite, CodedInputStreamRollback) { + { + protobuf_unittest::TestAllTypesLite m; + m.set_optional_bytes(std::string(30, 'a')); + std::string serialized = m.SerializeAsString(); + serialized += '\014'; + serialized += std::string(3, ' '); + io::ArrayInputStream is(serialized.data(), serialized.size(), + serialized.size() - 6); + { + io::CodedInputStream cis(&is); + m.Clear(); + m.MergePartialFromCodedStream(&cis); + EXPECT_TRUE(cis.LastTagWas(12)); + EXPECT_FALSE(cis.ConsumedEntireMessage()); + // Should leave is with 3 spaces; + } + const void* data; + int size; + ASSERT_TRUE(is.Next(&data, &size)); + ASSERT_EQ(size, 3); + EXPECT_EQ(memcmp(data, " ", 3), 0); + } + { + protobuf_unittest::TestPackedTypesLite m; + constexpr int kCount = 30; + for (int i = 0; i < kCount; i++) m.add_packed_fixed32(i); + std::string serialized = m.SerializeAsString(); + serialized += '\014'; + serialized += std::string(3, ' '); + // Buffer breaks in middle of a fixed32. + io::ArrayInputStream is(serialized.data(), serialized.size(), + serialized.size() - 7); + { + io::CodedInputStream cis(&is); + m.Clear(); + m.MergePartialFromCodedStream(&cis); + EXPECT_TRUE(cis.LastTagWas(12)); + EXPECT_FALSE(cis.ConsumedEntireMessage()); + // Should leave is with 3 spaces; + } + ASSERT_EQ(m.packed_fixed32_size(), kCount); + for (int i = 0; i < kCount; i++) EXPECT_EQ(m.packed_fixed32(i), i); + const void* data; + int size; + ASSERT_TRUE(is.Next(&data, &size)); + ASSERT_EQ(size, 3); + EXPECT_EQ(memcmp(data, " ", 3), 0); + } + { + protobuf_unittest::TestPackedTypesLite m; + constexpr int kCount = 30; + // Make sure we output 2 byte varints + for (int i = 0; i < kCount; i++) m.add_packed_fixed32(128 + i); + std::string serialized = m.SerializeAsString(); + serialized += '\014'; + serialized += std::string(3, ' '); + // Buffer breaks in middle of a 2 byte varint. + io::ArrayInputStream is(serialized.data(), serialized.size(), + serialized.size() - 5); + { + io::CodedInputStream cis(&is); + m.Clear(); + m.MergePartialFromCodedStream(&cis); + EXPECT_TRUE(cis.LastTagWas(12)); + EXPECT_FALSE(cis.ConsumedEntireMessage()); + // Should leave is with 3 spaces; + } + ASSERT_EQ(m.packed_fixed32_size(), kCount); + for (int i = 0; i < kCount; i++) EXPECT_EQ(m.packed_fixed32(i), i + 128); + const void* data; + int size; + ASSERT_TRUE(is.Next(&data, &size)); + ASSERT_EQ(size, 3); + EXPECT_EQ(memcmp(data, " ", 3), 0); + } +} + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index d5d71a012c..29c370c24c 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -337,6 +337,8 @@ struct MapPair { MapPair(const Key& other_first, const T& other_second) : first(other_first), second(other_second) {} explicit MapPair(const Key& other_first) : first(other_first), second() {} + explicit MapPair(Key&& other_first) + : first(std::move(other_first)), second() {} MapPair(const MapPair& other) : first(other.first), second(other.second) {} ~MapPair() {} @@ -685,7 +687,8 @@ class Map { // Insert the key into the map, if not present. In that case, the value will // be value initialized. - std::pair insert(const Key& k) { + template + std::pair insert(K&& k) { std::pair p = FindHelper(k); // Case 1: key was already present. if (p.first.node_ != nullptr) @@ -696,12 +699,18 @@ class Map { } const size_type b = p.second; // bucket number Node* node; + // If K is not key_type, make the conversion to key_type explicit. + using TypeToInit = typename std::conditional< + std::is_same::type, key_type>::value, K&&, + key_type>::type; if (alloc_.arena() == nullptr) { - node = new Node{value_type(k), nullptr}; + node = new Node{value_type(static_cast(std::forward(k))), + nullptr}; } else { node = Alloc(1); - Arena::CreateInArenaStorage(const_cast(&node->kv.first), - alloc_.arena(), k); + Arena::CreateInArenaStorage( + const_cast(&node->kv.first), alloc_.arena(), + static_cast(std::forward(k))); Arena::CreateInArenaStorage(&node->kv.second, alloc_.arena()); } @@ -710,7 +719,10 @@ class Map { return std::make_pair(result, true); } - value_type& operator[](const Key& k) { return *insert(k).first; } + template + value_type& operator[](K&& k) { + return *insert(std::forward(k)).first; + } void erase(iterator it) { GOOGLE_DCHECK_EQ(it.m_, this); @@ -1182,7 +1194,17 @@ class Map { bool empty() const { return size() == 0; } // Element access - T& operator[](const key_type& key) { return elements_[key].second; } + template + T& operator[](const key_arg& key) { + return elements_[key].second; + } + template < + typename K = key_type, + // Disable for integral types to reduce code bloat. + typename = typename std::enable_if::value>::type> + T& operator[](key_arg&& key) { + return elements_[std::forward(key)].second; + } template const T& at(const key_arg& key) const { diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 267abfb9a3..f2a5b93b8b 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -194,6 +194,62 @@ TEST_F(MapImplTest, OperatorBracket) { ExpectSingleElement(key, value2); } +struct MoveTestKey { + MoveTestKey(int data, int* copies) : data(data), copies(copies) {} + + MoveTestKey(const MoveTestKey& other) + : data(other.data), copies(other.copies) { + ++*copies; + } + + MoveTestKey(MoveTestKey&& other) noexcept + : data(other.data), copies(other.copies) {} + + friend bool operator==(const MoveTestKey& lhs, const MoveTestKey& rhs) { + return lhs.data == rhs.data; + } + friend bool operator<(const MoveTestKey& lhs, const MoveTestKey& rhs) { + return lhs.data < rhs.data; + } + + int data; + int* copies; +}; + +} // namespace +} // namespace internal +} // namespace protobuf +} // namespace google + +namespace std { + +template <> // NOLINT +struct hash { + size_t operator()(const google::protobuf::internal::MoveTestKey& key) const { + return hash{}(key.data); + } +}; +} // namespace std + +namespace google { +namespace protobuf { +namespace internal { +namespace { + +TEST_F(MapImplTest, OperatorBracketRValue) { + Arena arena; + for (Arena* arena_to_use : {&arena, static_cast(nullptr)}) { + int copies = 0; + Map map(arena_to_use); + MoveTestKey key1(1, &copies); + EXPECT_EQ(copies, 0); + map[key1] = 0; + EXPECT_EQ(copies, 1); + map[MoveTestKey(2, &copies)] = 2; + EXPECT_EQ(copies, 1); + } +} + TEST_F(MapImplTest, OperatorBracketNonExist) { int32 key = 0; int32 default_value = 0; @@ -1104,6 +1160,11 @@ void TestTransparent(const Key& key, const Key& miss_key) { EXPECT_EQ(m.erase(key), 0); EXPECT_EQ(m.erase(miss_key), 0); EXPECT_THAT(m, UnorderedElementsAre(Pair("DEF", 2))); + + m[key]; + EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 0), Pair("DEF", 2))); + m[key] = 1; + EXPECT_THAT(m, UnorderedElementsAre(Pair("ABC", 1), Pair("DEF", 2))); } TEST_F(MapImplTest, TransparentLookupForString) { diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index 7908544286..9c1a5940e6 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -570,7 +570,7 @@ inline bool MapTypeHandler::IsInitialized( template \ inline void MapTypeHandler::Clear( \ TypeOnMemory* value, Arena* arena) { \ - value->ClearToEmpty(&internal::GetEmptyStringAlreadyInited(), arena); \ + value->ClearToEmpty(); \ } \ template \ inline void MapTypeHandler::Merge( \ @@ -593,7 +593,7 @@ inline bool MapTypeHandler::IsInitialized( Type>::MapEntryAccessorType* \ MapTypeHandler::EnsureMutable( \ TypeOnMemory* value, Arena* arena) { \ - return value->Mutable(&internal::GetEmptyStringAlreadyInited(), arena); \ + return value->Mutable(ArenaStringPtr::EmptyDefault{}, arena); \ } \ template \ inline const typename MapTypeHandler +#define STR_HASH_FXN hash<::google::protobuf::StringPiece> class GeneratedMessageFactory : public MessageFactory { @@ -190,8 +190,8 @@ class GeneratedMessageFactory : public MessageFactory { private: // Only written at static init time, so does not require locking. - HASH_MAP + HASH_MAP file_map_; internal::WrappedMutex mutex_; diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 03a43841c4..8f5fef1220 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -1057,8 +1057,6 @@ class PROTOBUF_EXPORT Reflection final { internal::InternalMetadata* MutableInternalMetadata(Message* message) const; - inline bool IsInlined(const FieldDescriptor* field) const; - inline bool HasBit(const Message& message, const FieldDescriptor* field) const; inline void SetBit(Message* message, const FieldDescriptor* field) const; diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 5b1db7b9be..0e85991476 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -313,11 +313,11 @@ bool MessageLite::ParsePartialFromBoundedZeroCopyStream( return ParseFrom(internal::BoundedZCIS{input, size}); } -bool MessageLite::ParseFromString(const std::string& data) { +bool MessageLite::ParseFromString(ConstStringParam data) { return ParseFrom(data); } -bool MessageLite::ParsePartialFromString(const std::string& data) { +bool MessageLite::ParsePartialFromString(ConstStringParam data) { return ParseFrom(data); } @@ -329,7 +329,7 @@ bool MessageLite::ParsePartialFromArray(const void* data, int size) { return ParseFrom(as_string_view(data, size)); } -bool MessageLite::MergeFromString(const std::string& data) { +bool MessageLite::MergeFromString(ConstStringParam data) { return ParseFrom(data); } diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index c95e74c389..1cce5d9b08 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -315,12 +315,11 @@ class PROTOBUF_EXPORT MessageLite { // format, matching the encoding output by MessageLite::SerializeToString(). // If you'd like to convert a human-readable string into a protocol buffer // object, see google::protobuf::TextFormat::ParseFromString(). - PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromString( - const std::string& data); + PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromString(ConstStringParam data); // Like ParseFromString(), but accepts messages that are missing // required fields. PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParsePartialFromString( - const std::string& data); + ConstStringParam data); // Parse a protocol buffer contained in an array of bytes. PROTOBUF_ATTRIBUTE_REINITIALIZES bool ParseFromArray(const void* data, int size); @@ -351,7 +350,7 @@ class PROTOBUF_EXPORT MessageLite { bool MergePartialFromCodedStream(io::CodedInputStream* input); // Merge a protocol buffer contained in a string. - bool MergeFromString(const std::string& data); + bool MergeFromString(ConstStringParam data); // Serialization --------------------------------------------------- diff --git a/src/google/protobuf/parse_context.cc b/src/google/protobuf/parse_context.cc index 2a57465dfc..22cdcbba5b 100644 --- a/src/google/protobuf/parse_context.cc +++ b/src/google/protobuf/parse_context.cc @@ -48,7 +48,7 @@ namespace internal { namespace { // Only call if at start of tag. -bool ParseEndsInSlopRegion(const char* begin, int overrun, int d) { +bool ParseEndsInSlopRegion(const char* begin, int overrun, int depth) { constexpr int kSlopBytes = EpsCopyInputStream::kSlopBytes; GOOGLE_DCHECK(overrun >= 0); GOOGLE_DCHECK(overrun <= kSlopBytes); @@ -79,11 +79,11 @@ bool ParseEndsInSlopRegion(const char* begin, int overrun, int d) { break; } case 3: { // start group - d++; + depth++; break; } case 4: { // end group - if (--d < 0) return true; // We exit early + if (--depth < 0) return true; // We exit early break; } case 5: { // fixed32 @@ -99,7 +99,7 @@ bool ParseEndsInSlopRegion(const char* begin, int overrun, int d) { } // namespace -const char* EpsCopyInputStream::Next(int overrun, int d) { +const char* EpsCopyInputStream::NextBuffer(int overrun, int depth) { if (next_chunk_ == nullptr) return nullptr; // We've reached end of stream. if (next_chunk_ != buffer_) { GOOGLE_DCHECK(size_ > kSlopBytes); @@ -115,7 +115,7 @@ const char* EpsCopyInputStream::Next(int overrun, int d) { // buffer_. std::memmove(buffer_, buffer_end_, kSlopBytes); if (overall_limit_ > 0 && - (d < 0 || !ParseEndsInSlopRegion(buffer_, overrun, d))) { + (depth < 0 || !ParseEndsInSlopRegion(buffer_, overrun, depth))) { const void* data; // ZeroCopyInputStream indicates Next may return 0 size buffers. Hence // we loop. @@ -154,11 +154,22 @@ const char* EpsCopyInputStream::Next(int overrun, int d) { return buffer_; } -std::pair EpsCopyInputStream::DoneFallback(const char* ptr, - int d) { - GOOGLE_DCHECK(ptr >= limit_end_); - int overrun = ptr - buffer_end_; - GOOGLE_DCHECK(overrun <= kSlopBytes); // Guaranteed by parse loop. +const char* EpsCopyInputStream::Next() { + GOOGLE_DCHECK(limit_ > kSlopBytes); + auto p = NextBuffer(0 /* immaterial */, -1); + if (p == nullptr) { + limit_end_ = buffer_end_; + // Distinguish ending on a pushed limit or ending on end-of-stream. + SetEndOfStream(); + return nullptr; + } + limit_ -= buffer_end_ - p; // Adjust limit_ relative to new anchor + limit_end_ = buffer_end_ + std::min(0, limit_); + return p; +} + +std::pair EpsCopyInputStream::DoneFallback(int overrun, + int depth) { // Did we exceeded the limit (parse error). if (PROTOBUF_PREDICT_FALSE(overrun > limit_)) return {nullptr, true}; GOOGLE_DCHECK(overrun != limit_); // Guaranteed by caller. @@ -171,10 +182,11 @@ std::pair EpsCopyInputStream::DoneFallback(const char* ptr, // At this point we know the following assertion holds. GOOGLE_DCHECK(limit_ > 0); GOOGLE_DCHECK(limit_end_ == buffer_end_); // because limit_ > 0 + const char* p; do { // We are past the end of buffer_end_, in the slop region. GOOGLE_DCHECK(overrun >= 0); - auto p = Next(overrun, d); + p = NextBuffer(overrun, depth); if (p == nullptr) { // We are at the end of the stream if (PROTOBUF_PREDICT_FALSE(overrun != 0)) return {nullptr, true}; @@ -182,14 +194,14 @@ std::pair EpsCopyInputStream::DoneFallback(const char* ptr, limit_end_ = buffer_end_; // Distinguish ending on a pushed limit or ending on end-of-stream. SetEndOfStream(); - return {ptr, true}; + return {buffer_end_, true}; } limit_ -= buffer_end_ - p; // Adjust limit_ relative to new anchor - ptr = p + overrun; - overrun = ptr - buffer_end_; + p += overrun; + overrun = p - buffer_end_; } while (overrun >= 0); limit_end_ = buffer_end_ + std::min(0, limit_); - return {ptr, false}; + return {p, false}; } const char* EpsCopyInputStream::SkipFallback(const char* ptr, int size) { @@ -263,9 +275,11 @@ const char* EpsCopyInputStream::ReadPackedFixed(const char* ptr, int size, for (int i = 0; i < num; i++) dst[i] = UnalignedLoad(ptr + i * sizeof(T)); #endif - ptr += block_size; size -= block_size; - if (DoneWithCheck(&ptr, -1)) return nullptr; + if (limit_ <= kSlopBytes) return nullptr; + ptr = Next(); + if (ptr == nullptr) return nullptr; + ptr += kSlopBytes - (nbytes - block_size); nbytes = buffer_end_ + kSlopBytes - ptr; } int num = size / sizeof(T); diff --git a/src/google/protobuf/parse_context.h b/src/google/protobuf/parse_context.h index c5e3fda016..661008589d 100644 --- a/src/google/protobuf/parse_context.h +++ b/src/google/protobuf/parse_context.h @@ -208,9 +208,16 @@ class PROTOBUF_EXPORT EpsCopyInputStream { bool DoneWithCheck(const char** ptr, int d) { GOOGLE_DCHECK(*ptr); if (PROTOBUF_PREDICT_TRUE(*ptr < limit_end_)) return false; - // No need to fetch buffer if we ended on a limit in the slop region - if ((*ptr - buffer_end_) == limit_) return true; - auto res = DoneFallback(*ptr, d); + int overrun = *ptr - buffer_end_; + GOOGLE_DCHECK_LE(overrun, kSlopBytes); // Guaranteed by parse loop. + if (overrun == + limit_) { // No need to flip buffers if we ended on a limit. + // If we actually overrun the buffer and next_chunk_ is null. It means + // the stream ended and we passed the stream end. + if (overrun > 0 && next_chunk_ == nullptr) *ptr = nullptr; + return true; + } + auto res = DoneFallback(overrun, d); *ptr = res.first; return res.second; } @@ -276,8 +283,26 @@ class PROTOBUF_EXPORT EpsCopyInputStream { // systems. TODO(gerbens) do we need to set this as build flag? enum { kSafeStringSize = 50000000 }; - std::pair DoneFallback(const char* ptr, int d); - const char* Next(int overrun, int d); + // Advances to next buffer chunk returns a pointer to the same logical place + // in the stream as set by overrun. Overrun indicates the position in the slop + // region the parse was left (0 <= overrun <= kSlopBytes). Returns true if at + // limit, at which point the returned pointer maybe null if there was an + // error. The invariant of this function is that it's guaranteed that + // kSlopBytes bytes can be accessed from the returned ptr. This function might + // advance more buffers than one in the underlying ZeroCopyInputStream. + std::pair DoneFallback(int overrun, int depth); + // Advances to the next buffer, at most one call to Next() on the underlying + // ZeroCopyInputStream is made. This function DOES NOT match the returned + // pointer to where in the slop region the parse ends, hence no overrun + // parameter. This is useful for string operations where you always copy + // to the end of the buffer (including the slop region). + const char* Next(); + // overrun is the location in the slop region the stream currently is + // (0 <= overrun <= kSlopBytes). To prevent flipping to the next buffer of + // the ZeroCopyInputStream in the case the parse will end in the last + // kSlopBytes of the current buffer. depth is the current depth of nested + // groups (or negative if the use case does not need careful tracking). + inline const char* NextBuffer(int overrun, int depth); const char* SkipFallback(const char* ptr, int size); const char* AppendStringFallback(const char* ptr, int size, std::string* str); const char* ReadStringFallback(const char* ptr, int size, std::string* str); @@ -296,16 +321,17 @@ class PROTOBUF_EXPORT EpsCopyInputStream { int chunk_size = buffer_end_ + kSlopBytes - ptr; do { GOOGLE_DCHECK(size > chunk_size); + if (next_chunk_ == nullptr) return nullptr; append(ptr, chunk_size); ptr += chunk_size; size -= chunk_size; - // DoneFallBack asserts it isn't called when exactly on the limit. If this - // happens we fail the parse, as we are at the limit and still more bytes - // to read. - if (limit_ == kSlopBytes) return nullptr; - auto res = DoneFallback(ptr, -1); - if (res.second) return nullptr; // If done we passed the limit - ptr = res.first; + // TODO(gerbens) Next calls NextBuffer which generates buffers with + // overlap and thus incurs cost of copying the slop regions. This is not + // necessary for reading strings. We should just call Next buffers. + if (limit_ <= kSlopBytes) return nullptr; + ptr = Next(); + if (ptr == nullptr) return nullptr; // passed the limit + ptr += kSlopBytes; chunk_size = buffer_end_ + kSlopBytes - ptr; } while (size > chunk_size); append(ptr, size); @@ -319,11 +345,19 @@ class PROTOBUF_EXPORT EpsCopyInputStream { // implicit weak messages. We keep these methods private and friend them. template const char* AppendUntilEnd(const char* ptr, const A& append) { - while (!DoneWithCheck(&ptr, -1)) { - append(ptr, limit_end_ - ptr); - ptr = limit_end_; + if (ptr - buffer_end_ > limit_) return nullptr; + while (limit_ > kSlopBytes) { + int chunk_size = buffer_end_ + kSlopBytes - ptr; + GOOGLE_DCHECK_GE(chunk_size, 0); + append(ptr, chunk_size); + ptr = Next(); + if (ptr == nullptr) return limit_end_; + ptr += kSlopBytes; } - return ptr; + auto end = buffer_end_ + limit_; + GOOGLE_DCHECK(end >= ptr); + append(ptr, end - ptr); + return end; } PROTOBUF_MUST_USE_RESULT const char* AppendString(const char* ptr, @@ -354,7 +388,6 @@ class PROTOBUF_EXPORT ParseContext : public EpsCopyInputStream { void TrackCorrectEnding() { group_depth_ = 0; } bool Done(const char** ptr) { return DoneWithCheck(ptr, group_depth_); } - bool DoneNoSlopCheck(const char** ptr) { return DoneWithCheck(ptr, -1); } int depth() const { return depth_; } @@ -619,21 +652,52 @@ PROTOBUF_MUST_USE_RESULT const char* ParseContext::ParseMessage( } template -const char* EpsCopyInputStream::ReadPackedVarint(const char* ptr, Add add) { - int size = ReadSize(&ptr); - if (ptr == nullptr) return nullptr; - auto old = PushLimit(ptr, size); - if (old < 0) return nullptr; - while (!DoneWithCheck(&ptr, -1)) { +const char* ReadPackedVarintArray(const char* ptr, const char* end, Add add) { + while (ptr < end) { uint64 varint; ptr = VarintParse(ptr, &varint); - if (!ptr) return nullptr; + if (ptr == nullptr) return nullptr; add(varint); } - if (!PopLimit(old)) return nullptr; return ptr; } +template +const char* EpsCopyInputStream::ReadPackedVarint(const char* ptr, Add add) { + int size = ReadSize(&ptr); + if (ptr == nullptr) return nullptr; + int chunk_size = buffer_end_ - ptr; + while (size > chunk_size) { + ptr = ReadPackedVarintArray(ptr, buffer_end_, add); + if (ptr == nullptr) return nullptr; + int overrun = ptr - buffer_end_; + GOOGLE_DCHECK(overrun >= 0 && overrun <= kSlopBytes); + if (size - chunk_size <= kSlopBytes) { + // The current buffer contains all the information needed, we don't need + // to flip buffers. However we must parse from a buffer with enough space + // so we are not prone to a buffer overflow. + char buf[kSlopBytes + 10] = {}; + std::memcpy(buf, buffer_end_, kSlopBytes); + GOOGLE_CHECK_LE(size - chunk_size, kSlopBytes); + auto end = buf + (size - chunk_size); + auto res = ReadPackedVarintArray(buf + overrun, end, add); + if (res == nullptr || res != end) return nullptr; + return buffer_end_ + (res - buf); + } + size -= overrun + chunk_size; + GOOGLE_DCHECK_GT(size, 0); + // We must flip buffers + if (limit_ <= kSlopBytes) return nullptr; + ptr = Next(); + if (ptr == nullptr) return nullptr; + ptr += overrun; + chunk_size = buffer_end_ - ptr; + } + auto end = ptr + size; + ptr = ReadPackedVarintArray(ptr, end, add); + return end == ptr ? ptr : nullptr; +} + // Helper for verification of utf8 PROTOBUF_EXPORT bool VerifyUTF8(StringPiece s, const char* field_name); diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index 74c2518096..d879a863b0 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -238,12 +238,15 @@ #ifdef GOOGLE_PROTOBUF_ATTRIBUTE_RETURNS_NONNULL #define PROTOBUF_RETURNS_NONNULL GOOGLE_PROTOBUF_ATTRIBUTE_RETURNS_NONNULL #else -#ifdef __GNUC__ +#if defined(__has_attribute) +#if __has_attribute(returns_nonnull) #define PROTOBUF_RETURNS_NONNULL __attribute__((returns_nonnull)) -#else -#define PROTOBUF_RETURNS_NONNULL #endif #endif +#endif +#ifndef PROTOBUF_RETURNS_NONNULL +#define PROTOBUF_RETURNS_NONNULL +#endif #if defined(__has_cpp_attribute) #if __has_cpp_attribute(clang::reinitializes) @@ -433,6 +436,8 @@ #undef SEVERITY_ERROR #pragma push_macro("STRICT") #undef STRICT +#pragma push_macro("timezone") +#undef timezone #endif // _MSC_VER #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 6b3751055f..fd080a4875 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -93,6 +93,7 @@ #pragma pop_macro("SERVICE_DISABLED") #pragma pop_macro("SEVERITY_ERROR") #pragma pop_macro("STRICT") +#pragma pop_macro("timezone") #endif #if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER) diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc index ce3f091df9..c913ea0d19 100644 --- a/src/google/protobuf/reflection_ops.cc +++ b/src/google/protobuf/reflection_ops.cc @@ -43,7 +43,6 @@ #include #include #include -#include #include diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index 925686972a..a9e0f843d3 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -95,7 +95,7 @@ SourceContext::SourceContext(const SourceContext& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); file_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_file_name().empty()) { - file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_file_name(), + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_file_name(), GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.SourceContext) @@ -138,7 +138,7 @@ void SourceContext::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - file_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + file_name_.ClearToEmpty(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 4722d10ef6..9d08789d46 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -220,7 +219,7 @@ class PROTOBUF_EXPORT SourceContext PROTOBUF_FINAL : // string file_name = 1; inline void SourceContext::clear_file_name() { - file_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + file_name_.ClearToEmpty(); } inline const std::string& SourceContext::file_name() const { // @@protoc_insertion_point(field_get:google.protobuf.SourceContext.file_name) @@ -239,31 +238,30 @@ inline const std::string& SourceContext::_internal_file_name() const { } inline void SourceContext::_internal_set_file_name(const std::string& value) { - file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void SourceContext::set_file_name(std::string&& value) { file_name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.SourceContext.file_name) } inline void SourceContext::set_file_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name) } inline void SourceContext::set_file_name(const char* value, size_t size) { - file_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + file_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.SourceContext.file_name) } inline std::string* SourceContext::_internal_mutable_file_name() { - return file_name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return file_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* SourceContext::release_file_name() { // @@protoc_insertion_point(field_release:google.protobuf.SourceContext.file_name) diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index d94b86d2c7..a6d9095303 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -547,7 +547,7 @@ void Value::clear_kind() { break; } case kStringValue: { - kind_.string_value_.Destroy(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + kind_.string_value_.Destroy(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); break; } case kBoolValue: { diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 315193c421..b28bdc8461 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -807,7 +806,7 @@ inline void Value::set_has_string_value() { } inline void Value::clear_string_value() { if (_internal_has_string_value()) { - kind_.string_value_.Destroy(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + kind_.string_value_.Destroy(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); clear_has_kind(); } } @@ -827,7 +826,7 @@ inline const std::string& Value::_internal_string_value() const { if (_internal_has_string_value()) { return kind_.string_value_.Get(); } - return *&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(); + return ::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(); } inline void Value::_internal_set_string_value(const std::string& value) { if (!_internal_has_string_value()) { @@ -835,7 +834,7 @@ inline void Value::_internal_set_string_value(const std::string& value) { set_has_string_value(); kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } - kind_.string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + kind_.string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Value::set_string_value(std::string&& value) { // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) @@ -845,7 +844,7 @@ inline void Value::set_string_value(std::string&& value) { kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } kind_.string_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Value.string_value) } inline void Value::set_string_value(const char* value) { @@ -855,7 +854,7 @@ inline void Value::set_string_value(const char* value) { set_has_string_value(); kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } - kind_.string_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), + kind_.string_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Value.string_value) } @@ -867,7 +866,7 @@ inline void Value::set_string_value(const char* value, kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } kind_.string_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Value.string_value) @@ -878,13 +877,14 @@ inline std::string* Value::_internal_mutable_string_value() { set_has_string_value(); kind_.string_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); } - return kind_.string_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return kind_.string_value_.Mutable( + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Value::release_string_value() { // @@protoc_insertion_point(field_release:google.protobuf.Value.string_value) if (_internal_has_string_value()) { clear_has_kind(); - return kind_.string_value_.Release(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return kind_.string_value_.ReleaseNonDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); } else { return nullptr; } diff --git a/src/google/protobuf/stubs/fastmem.h b/src/google/protobuf/stubs/fastmem.h deleted file mode 100644 index 76c8a3aea6..0000000000 --- a/src/google/protobuf/stubs/fastmem.h +++ /dev/null @@ -1,157 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2014 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Fast memory copying and comparison routines. -// strings::fastmemcmp_inlined() replaces memcmp() -// strings::memcpy_inlined() replaces memcpy() -// strings::memeq(a, b, n) replaces memcmp(a, b, n) == 0 -// -// strings::*_inlined() routines are inline versions of the -// routines exported by this module. Sometimes using the inlined -// versions is faster. Measure before using the inlined versions. -// -// Performance measurement: -// strings::fastmemcmp_inlined -// Analysis: memcmp, fastmemcmp_inlined, fastmemcmp -// 2012-01-30 - -#ifndef GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ -#define GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ - -#include -#include -#include - -#include - -#include - -namespace google { -namespace protobuf { -namespace internal { - -// Return true if the n bytes at a equal the n bytes at b. -// The regions are allowed to overlap. -// -// The performance is similar to the performance memcmp(), but faster for -// moderately-sized inputs, or inputs that share a common prefix and differ -// somewhere in their last 8 bytes. Further optimizations can be added later -// if it makes sense to do so.:w -inline bool memeq(const char* a, const char* b, size_t n) { - size_t n_rounded_down = n & ~static_cast(7); - if (PROTOBUF_PREDICT_FALSE(n_rounded_down == 0)) { // n <= 7 - return memcmp(a, b, n) == 0; - } - // n >= 8 - uint64 u = GOOGLE_UNALIGNED_LOAD64(a) ^ GOOGLE_UNALIGNED_LOAD64(b); - uint64 v = GOOGLE_UNALIGNED_LOAD64(a + n - 8) ^ GOOGLE_UNALIGNED_LOAD64(b + n - 8); - if ((u | v) != 0) { // The first or last 8 bytes differ. - return false; - } - a += 8; - b += 8; - n = n_rounded_down - 8; - if (n > 128) { - // As of 2012, memcmp on x86-64 uses a big unrolled loop with SSE2 - // instructions, and while we could try to do something faster, it - // doesn't seem worth pursuing. - return memcmp(a, b, n) == 0; - } - for (; n >= 16; n -= 16) { - uint64 x = GOOGLE_UNALIGNED_LOAD64(a) ^ GOOGLE_UNALIGNED_LOAD64(b); - uint64 y = GOOGLE_UNALIGNED_LOAD64(a + 8) ^ GOOGLE_UNALIGNED_LOAD64(b + 8); - if ((x | y) != 0) { - return false; - } - a += 16; - b += 16; - } - // n must be 0 or 8 now because it was a multiple of 8 at the top of the loop. - return n == 0 || GOOGLE_UNALIGNED_LOAD64(a) == GOOGLE_UNALIGNED_LOAD64(b); -} - -inline int fastmemcmp_inlined(const char *a, const char *b, size_t n) { - if (n >= 64) { - return memcmp(a, b, n); - } - const char* a_limit = a + n; - while (a + sizeof(uint64) <= a_limit && - GOOGLE_UNALIGNED_LOAD64(a) == GOOGLE_UNALIGNED_LOAD64(b)) { - a += sizeof(uint64); - b += sizeof(uint64); - } - if (a + sizeof(uint32) <= a_limit && - GOOGLE_UNALIGNED_LOAD32(a) == GOOGLE_UNALIGNED_LOAD32(b)) { - a += sizeof(uint32); - b += sizeof(uint32); - } - while (a < a_limit) { - int d = - static_cast(static_cast(*a++) - static_cast(*b++)); - if (d) return d; - } - return 0; -} - -// The standard memcpy operation is slow for variable small sizes. -// This implementation inlines the optimal realization for sizes 1 to 16. -// To avoid code bloat don't use it in case of not performance-critical spots, -// nor when you don't expect very frequent values of size <= 16. -inline void memcpy_inlined(char *dst, const char *src, size_t size) { - // Compiler inlines code with minimal amount of data movement when third - // parameter of memcpy is a constant. - switch (size) { - case 1: memcpy(dst, src, 1); break; - case 2: memcpy(dst, src, 2); break; - case 3: memcpy(dst, src, 3); break; - case 4: memcpy(dst, src, 4); break; - case 5: memcpy(dst, src, 5); break; - case 6: memcpy(dst, src, 6); break; - case 7: memcpy(dst, src, 7); break; - case 8: memcpy(dst, src, 8); break; - case 9: memcpy(dst, src, 9); break; - case 10: memcpy(dst, src, 10); break; - case 11: memcpy(dst, src, 11); break; - case 12: memcpy(dst, src, 12); break; - case 13: memcpy(dst, src, 13); break; - case 14: memcpy(dst, src, 14); break; - case 15: memcpy(dst, src, 15); break; - case 16: memcpy(dst, src, 16); break; - default: memcpy(dst, src, size); break; - } -} - -} // namespace internal -} // namespace protobuf -} // namespace google - -#include - -#endif // GOOGLE_PROTOBUF_STUBS_FASTMEM_H_ diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h index e2d239279f..a7ec068074 100644 --- a/src/google/protobuf/stubs/hash.h +++ b/src/google/protobuf/stubs/hash.h @@ -108,14 +108,6 @@ struct hash > { } }; -// Used by GCC/SGI STL only. (Why isn't this provided by the standard -// library? :( ) -struct streq { - inline bool operator()(const char* a, const char* b) const { - return strcmp(a, b) == 0; - } -}; - } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 11e9b0001f..323b0e0999 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -456,8 +456,7 @@ class TextFormat::Parser::ParserImpl { DO(ConsumeIdentifier(&field_name)); int32 field_number; - if (allow_field_number_ && - safe_strto32(field_name, &field_number)) { + if (allow_field_number_ && safe_strto32(field_name, &field_number)) { if (descriptor->IsExtensionNumber(field_number)) { field = finder_ ? finder_->FindExtensionByNumber(descriptor, field_number) @@ -1473,7 +1472,7 @@ bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, return MergeUsingImpl(input, output, &parser); } -bool TextFormat::Parser::MergeFromString(const std::string& input, +bool TextFormat::Parser::MergeFromString(ConstStringParam input, Message* output) { DO(CheckParseInputSize(input, error_collector_)); io::ArrayInputStream input_stream(input.data(), input.size()); @@ -1524,7 +1523,7 @@ bool TextFormat::Parser::ParseFieldValueFromString(const std::string& input, return Parser().ParseFromString(input, output); } -/* static */ bool TextFormat::MergeFromString(const std::string& input, +/* static */ bool TextFormat::MergeFromString(ConstStringParam input, Message* output) { return Parser().MergeFromString(input, output); } diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index e4b32557f4..3a3ee1563a 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -460,7 +460,7 @@ class PROTOBUF_EXPORT TextFormat { // using Message::MergeFrom(). static bool Merge(io::ZeroCopyInputStream* input, Message* output); // Like Merge(), but reads directly from a string. - static bool MergeFromString(const std::string& input, Message* output); + static bool MergeFromString(ConstStringParam input, Message* output); // Parse the given text as a single field value and store it into the // given field of the given message. If the field is a repeated field, @@ -535,7 +535,7 @@ class PROTOBUF_EXPORT TextFormat { // Like TextFormat::Merge(). bool Merge(io::ZeroCopyInputStream* input, Message* output); // Like TextFormat::MergeFromString(). - bool MergeFromString(const std::string& input, Message* output); + bool MergeFromString(ConstStringParam input, Message* output); // Set where to report parse errors. If NULL (the default), errors will // be printed to stderr. @@ -569,16 +569,22 @@ class PROTOBUF_EXPORT TextFormat { const FieldDescriptor* field, Message* output); - // When an unknown extension is met, parsing will fail if this option is set - // to false (the default). If true, unknown extensions will be ignored and - // a warning message will be generated. + // When an unknown extension is met, parsing will fail if this option is + // set to false (the default). If true, unknown extensions will be ignored + // and a warning message will be generated. + // Beware! Setting this option true may hide some errors (e.g. spelling + // error on extension name). This allows data loss; unlike binary format, + // text format cannot preserve unknown extensions. Avoid using this option + // if possible. void AllowUnknownExtension(bool allow) { allow_unknown_extension_ = allow; } // When an unknown field is met, parsing will fail if this option is set - // to false(the default). If true, unknown fields will be ignored and + // to false (the default). If true, unknown fields will be ignored and // a warning message will be generated. - // Please aware that set this option true may hide some errors (e.g. - // spelling error on field name). Avoid to use this option if possible. + // Beware! Setting this option true may hide some errors (e.g. spelling + // error on field name). This allows data loss; unlike binary format, text + // format cannot preserve unknown fields. Avoid using this option + // if possible. void AllowUnknownField(bool allow) { allow_unknown_field_ = allow; } diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index da7ebe9f72..875f8f3069 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 01a79f976b..a320ee6a4a 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -381,7 +381,7 @@ Type::Type(const Type& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } if (from._internal_has_source_context()) { @@ -437,7 +437,7 @@ void Type::Clear() { fields_.Clear(); oneofs_.Clear(); options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } @@ -755,22 +755,22 @@ Field::Field(const Field& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_type_url().empty()) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_type_url(), + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_type_url(), GetArena()); } json_name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_json_name().empty()) { - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_json_name(), + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_json_name(), GetArena()); } default_value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_default_value().empty()) { - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_default_value(), + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_default_value(), GetArena()); } ::memcpy(&kind_, &from.kind_, @@ -826,10 +826,10 @@ void Field::Clear() { (void) cached_has_bits; options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); - type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); - json_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); - default_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); + type_url_.ClearToEmpty(); + json_name_.ClearToEmpty(); + default_value_.ClearToEmpty(); ::memset(&kind_, 0, static_cast( reinterpret_cast(&packed_) - reinterpret_cast(&kind_)) + sizeof(packed_)); @@ -1251,7 +1251,7 @@ Enum::Enum(const Enum& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } if (from._internal_has_source_context()) { @@ -1306,7 +1306,7 @@ void Enum::Clear() { enumvalue_.Clear(); options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); if (GetArena() == nullptr && source_context_ != nullptr) { delete source_context_; } @@ -1590,7 +1590,7 @@ EnumValue::EnumValue(const EnumValue& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } number_ = from.number_; @@ -1636,7 +1636,7 @@ void EnumValue::Clear() { (void) cached_has_bits; options_.Clear(); - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); number_ = 0; _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } @@ -1865,7 +1865,7 @@ Option::Option(const Option& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_name().empty()) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_name(), + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_name(), GetArena()); } if (from._internal_has_value()) { @@ -1915,7 +1915,7 @@ void Option::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); if (GetArena() == nullptr && value_ != nullptr) { delete value_; } diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index f761361790..a11617b13c 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -1351,7 +1350,7 @@ class PROTOBUF_EXPORT Option PROTOBUF_FINAL : // string name = 1; inline void Type::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); } inline const std::string& Type::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Type.name) @@ -1370,31 +1369,30 @@ inline const std::string& Type::_internal_name() const { } inline void Type::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Type::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Type.name) } inline void Type::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Type.name) } inline void Type::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Type.name) } inline std::string* Type::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Type::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Type.name) @@ -1726,7 +1724,7 @@ inline void Field::set_number(::PROTOBUF_NAMESPACE_ID::int32 value) { // string name = 4; inline void Field::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); } inline const std::string& Field::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Field.name) @@ -1745,31 +1743,30 @@ inline const std::string& Field::_internal_name() const { } inline void Field::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Field::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.name) } inline void Field::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Field.name) } inline void Field::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.name) } inline std::string* Field::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Field::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Field.name) @@ -1788,7 +1785,7 @@ inline void Field::set_allocated_name(std::string* name) { // string type_url = 6; inline void Field::clear_type_url() { - type_url_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + type_url_.ClearToEmpty(); } inline const std::string& Field::type_url() const { // @@protoc_insertion_point(field_get:google.protobuf.Field.type_url) @@ -1807,31 +1804,30 @@ inline const std::string& Field::_internal_type_url() const { } inline void Field::_internal_set_type_url(const std::string& value) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Field::set_type_url(std::string&& value) { type_url_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.type_url) } inline void Field::set_type_url(const char* value) { GOOGLE_DCHECK(value != nullptr); - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Field.type_url) } inline void Field::set_type_url(const char* value, size_t size) { - type_url_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + type_url_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.type_url) } inline std::string* Field::_internal_mutable_type_url() { - return type_url_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return type_url_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Field::release_type_url() { // @@protoc_insertion_point(field_release:google.protobuf.Field.type_url) @@ -1929,7 +1925,7 @@ Field::options() const { // string json_name = 10; inline void Field::clear_json_name() { - json_name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + json_name_.ClearToEmpty(); } inline const std::string& Field::json_name() const { // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name) @@ -1948,31 +1944,30 @@ inline const std::string& Field::_internal_json_name() const { } inline void Field::_internal_set_json_name(const std::string& value) { - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Field::set_json_name(std::string&& value) { json_name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.json_name) } inline void Field::set_json_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name) } inline void Field::set_json_name(const char* value, size_t size) { - json_name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + json_name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name) } inline std::string* Field::_internal_mutable_json_name() { - return json_name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return json_name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Field::release_json_name() { // @@protoc_insertion_point(field_release:google.protobuf.Field.json_name) @@ -1991,7 +1986,7 @@ inline void Field::set_allocated_json_name(std::string* json_name) { // string default_value = 11; inline void Field::clear_default_value() { - default_value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + default_value_.ClearToEmpty(); } inline const std::string& Field::default_value() const { // @@protoc_insertion_point(field_get:google.protobuf.Field.default_value) @@ -2010,31 +2005,30 @@ inline const std::string& Field::_internal_default_value() const { } inline void Field::_internal_set_default_value(const std::string& value) { - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Field::set_default_value(std::string&& value) { default_value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Field.default_value) } inline void Field::set_default_value(const char* value) { GOOGLE_DCHECK(value != nullptr); - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Field.default_value) } inline void Field::set_default_value(const char* value, size_t size) { - default_value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + default_value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.default_value) } inline std::string* Field::_internal_mutable_default_value() { - return default_value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return default_value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Field::release_default_value() { // @@protoc_insertion_point(field_release:google.protobuf.Field.default_value) @@ -2057,7 +2051,7 @@ inline void Field::set_allocated_default_value(std::string* default_value) { // string name = 1; inline void Enum::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); } inline const std::string& Enum::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Enum.name) @@ -2076,31 +2070,30 @@ inline const std::string& Enum::_internal_name() const { } inline void Enum::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Enum::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Enum.name) } inline void Enum::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Enum.name) } inline void Enum::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Enum.name) } inline std::string* Enum::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Enum::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Enum.name) @@ -2298,7 +2291,7 @@ inline void Enum::set_syntax(PROTOBUF_NAMESPACE_ID::Syntax value) { // string name = 1; inline void EnumValue::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); } inline const std::string& EnumValue::name() const { // @@protoc_insertion_point(field_get:google.protobuf.EnumValue.name) @@ -2317,31 +2310,30 @@ inline const std::string& EnumValue::_internal_name() const { } inline void EnumValue::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void EnumValue::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.EnumValue.name) } inline void EnumValue::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValue.name) } inline void EnumValue::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.EnumValue.name) } inline std::string* EnumValue::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* EnumValue::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.EnumValue.name) @@ -2423,7 +2415,7 @@ EnumValue::options() const { // string name = 1; inline void Option::clear_name() { - name_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + name_.ClearToEmpty(); } inline const std::string& Option::name() const { // @@protoc_insertion_point(field_get:google.protobuf.Option.name) @@ -2442,31 +2434,30 @@ inline const std::string& Option::_internal_name() const { } inline void Option::_internal_set_name(const std::string& value) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void Option::set_name(std::string&& value) { name_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.Option.name) } inline void Option::set_name(const char* value) { GOOGLE_DCHECK(value != nullptr); - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.Option.name) } inline void Option::set_name(const char* value, size_t size) { - name_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + name_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.Option.name) } inline std::string* Option::_internal_mutable_name() { - return name_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return name_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* Option::release_name() { // @@protoc_insertion_point(field_release:google.protobuf.Option.name) diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc index e76268a9d5..4246956f55 100644 --- a/src/google/protobuf/util/internal/datapiece.cc +++ b/src/google/protobuf/util/internal/datapiece.cc @@ -47,7 +47,6 @@ namespace util { namespace converter { using util::Status; -using util::StatusOr; using util::error::Code; namespace { @@ -57,7 +56,7 @@ inline Status InvalidArgument(StringPiece value_str) { } template -StatusOr ValidateNumberConversion(To after, From before) { +util::StatusOr ValidateNumberConversion(To after, From before) { if (after == before && MathUtil::Sign(before) == MathUtil::Sign(after)) { return after; @@ -74,7 +73,7 @@ StatusOr ValidateNumberConversion(To after, From before) { // int32, int64, uint32, uint64, double and float // except conversion between double and float. template -StatusOr NumberConvertAndCheck(From before) { +util::StatusOr NumberConvertAndCheck(From before) { if (std::is_same::value) return before; To after = static_cast(before); @@ -84,7 +83,7 @@ StatusOr NumberConvertAndCheck(From before) { // For conversion to integer types (int32, int64, uint32, uint64) from floating // point types (double, float) only. template -StatusOr FloatingPointToIntConvertAndCheck(From before) { +util::StatusOr FloatingPointToIntConvertAndCheck(From before) { if (std::is_same::value) return before; To after = static_cast(before); @@ -92,13 +91,13 @@ StatusOr FloatingPointToIntConvertAndCheck(From before) { } // For conversion between double and float only. -StatusOr FloatToDouble(float before) { +util::StatusOr FloatToDouble(float before) { // Casting float to double should just work as double has more precision // than float. return static_cast(before); } -StatusOr DoubleToFloat(double before) { +util::StatusOr DoubleToFloat(double before) { if (std::isnan(before)) { return std::numeric_limits::quiet_NaN(); } else if (!std::isfinite(before)) { @@ -115,7 +114,7 @@ StatusOr DoubleToFloat(double before) { } // namespace -StatusOr DataPiece::ToInt32() const { +util::StatusOr DataPiece::ToInt32() const { if (type_ == TYPE_STRING) return StringToNumber(safe_strto32); if (type_ == TYPE_DOUBLE) @@ -127,7 +126,7 @@ StatusOr DataPiece::ToInt32() const { return GenericConvert(); } -StatusOr DataPiece::ToUint32() const { +util::StatusOr DataPiece::ToUint32() const { if (type_ == TYPE_STRING) return StringToNumber(safe_strtou32); @@ -140,7 +139,7 @@ StatusOr DataPiece::ToUint32() const { return GenericConvert(); } -StatusOr DataPiece::ToInt64() const { +util::StatusOr DataPiece::ToInt64() const { if (type_ == TYPE_STRING) return StringToNumber(safe_strto64); if (type_ == TYPE_DOUBLE) @@ -152,7 +151,7 @@ StatusOr DataPiece::ToInt64() const { return GenericConvert(); } -StatusOr DataPiece::ToUint64() const { +util::StatusOr DataPiece::ToUint64() const { if (type_ == TYPE_STRING) return StringToNumber(safe_strtou64); @@ -165,7 +164,7 @@ StatusOr DataPiece::ToUint64() const { return GenericConvert(); } -StatusOr DataPiece::ToDouble() const { +util::StatusOr DataPiece::ToDouble() const { if (type_ == TYPE_FLOAT) { return FloatToDouble(float_); } @@ -173,7 +172,7 @@ StatusOr DataPiece::ToDouble() const { if (str_ == "Infinity") return std::numeric_limits::infinity(); if (str_ == "-Infinity") return -std::numeric_limits::infinity(); if (str_ == "NaN") return std::numeric_limits::quiet_NaN(); - StatusOr value = StringToNumber(safe_strtod); + util::StatusOr value = StringToNumber(safe_strtod); if (value.ok() && !std::isfinite(value.value())) { // safe_strtod converts out-of-range values to +inf/-inf, but we want // to report them as errors. @@ -185,7 +184,7 @@ StatusOr DataPiece::ToDouble() const { return GenericConvert(); } -StatusOr DataPiece::ToFloat() const { +util::StatusOr DataPiece::ToFloat() const { if (type_ == TYPE_DOUBLE) { return DoubleToFloat(double_); } @@ -200,7 +199,7 @@ StatusOr DataPiece::ToFloat() const { return GenericConvert(); } -StatusOr DataPiece::ToBool() const { +util::StatusOr DataPiece::ToBool() const { switch (type_) { case TYPE_BOOL: return bool_; @@ -212,7 +211,7 @@ StatusOr DataPiece::ToBool() const { } } -StatusOr DataPiece::ToString() const { +util::StatusOr DataPiece::ToString() const { switch (type_) { case TYPE_STRING: return std::string(str_); @@ -258,7 +257,7 @@ std::string DataPiece::ValueAsStringOrDefault( } } -StatusOr DataPiece::ToBytes() const { +util::StatusOr DataPiece::ToBytes() const { if (type_ == TYPE_BYTES) return str_.ToString(); if (type_ == TYPE_STRING) { std::string decoded; @@ -272,11 +271,11 @@ StatusOr DataPiece::ToBytes() const { } } -StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, - bool use_lower_camel_for_enums, - bool case_insensitive_enum_parsing, - bool ignore_unknown_enum_values, - bool* is_unknown_enum_value) const { +util::StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_enum_values, + bool* is_unknown_enum_value) const { if (type_ == TYPE_NULL) return google::protobuf::NULL_VALUE; if (type_ == TYPE_STRING) { @@ -287,7 +286,7 @@ StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, if (value != nullptr) return value->number(); // Check if int version of enum is sent as string. - StatusOr int_value = ToInt32(); + util::StatusOr int_value = ToInt32(); if (int_value.ok()) { if (const google::protobuf::EnumValue* enum_value = FindEnumValueByNumberOrNull(enum_type, int_value.value())) { @@ -332,7 +331,7 @@ StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, } template -StatusOr DataPiece::GenericConvert() const { +util::StatusOr DataPiece::GenericConvert() const { switch (type_) { case TYPE_INT32: return NumberConvertAndCheck(i32_); @@ -354,8 +353,8 @@ StatusOr DataPiece::GenericConvert() const { } template -StatusOr DataPiece::StringToNumber(bool (*func)(StringPiece, - To*)) const { +util::StatusOr DataPiece::StringToNumber(bool (*func)(StringPiece, + To*)) const { if (str_.size() > 0 && (str_[0] == ' ' || str_[str_.size() - 1] == ' ')) { return InvalidArgument(StrCat("\"", str_, "\"")); } diff --git a/src/google/protobuf/util/internal/datapiece.h b/src/google/protobuf/util/internal/datapiece.h index 1b0ccfa244..38ced17277 100644 --- a/src/google/protobuf/util/internal/datapiece.h +++ b/src/google/protobuf/util/internal/datapiece.h @@ -167,10 +167,10 @@ class PROTOBUF_EXPORT DataPiece { // Same as the ToEnum() method above but with additional flag to ignore // unknown enum values. util::StatusOr ToEnum(const google::protobuf::Enum* enum_type, - bool use_lower_camel_for_enums, - bool case_insensitive_enum_parsing, - bool ignore_unknown_enum_values, - bool* is_unknown_enum_value) const; + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_enum_values, + bool* is_unknown_enum_value) const; // For numeric conversion between // int32, int64, uint32, uint64, double, float and bool @@ -180,8 +180,7 @@ class PROTOBUF_EXPORT DataPiece { // For conversion from string to // int32, int64, uint32, uint64, double, float and bool template - util::StatusOr StringToNumber(bool (*func)(StringPiece, - To*)) const; + util::StatusOr StringToNumber(bool (*func)(StringPiece, To*)) const; // Decodes a base64 string. Returns true on success. bool DecodeBase64(StringPiece src, std::string* dest) const; diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index a78a862eb0..60a44dbe52 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -40,7 +40,6 @@ namespace google { namespace protobuf { namespace util { using util::Status; -using util::StatusOr; namespace converter { namespace { @@ -49,9 +48,10 @@ namespace { // If value is empty or if conversion fails, the default_value is returned. template T ConvertTo(StringPiece value, - StatusOr (DataPiece::*converter_fn)() const, T default_value) { + util::StatusOr (DataPiece::*converter_fn)() const, + T default_value) { if (value.empty()) return default_value; - StatusOr result = (DataPiece(value, true).*converter_fn)(); + util::StatusOr result = (DataPiece(value, true).*converter_fn)(); return result.ok() ? result.value() : default_value; } } // namespace diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc index 8cb22c79a8..0a321386a1 100644 --- a/src/google/protobuf/util/internal/json_stream_parser.cc +++ b/src/google/protobuf/util/internal/json_stream_parser.cc @@ -853,7 +853,7 @@ util::Status JsonStreamParser::ReportUnknown(StringPiece message) { util::Status JsonStreamParser::IncrementRecursionDepth( StringPiece key) const { if (++recursion_depth_ > max_recursion_depth_) { - return Status( + return util::Status( util::error::INVALID_ARGUMENT, StrCat("Message too deep. Max recursion depth reached for key '", key, "'")); diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index de93085efa..240db516a4 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc @@ -55,7 +55,6 @@ namespace converter { using io::CodedOutputStream; using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; using util::Status; -using util::StatusOr; using util::error::INVALID_ARGUMENT; @@ -120,9 +119,9 @@ ProtoWriter::~ProtoWriter() { namespace { // Writes an INT32 field, including tag to the stream. -inline Status WriteInt32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i32 = data.ToInt32(); +inline util::Status WriteInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i32 = data.ToInt32(); if (i32.ok()) { WireFormatLite::WriteInt32(field_number, i32.value(), stream); } @@ -130,9 +129,9 @@ inline Status WriteInt32(int field_number, const DataPiece& data, } // writes an SFIXED32 field, including tag, to the stream. -inline Status WriteSFixed32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i32 = data.ToInt32(); +inline util::Status WriteSFixed32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i32 = data.ToInt32(); if (i32.ok()) { WireFormatLite::WriteSFixed32(field_number, i32.value(), stream); } @@ -140,9 +139,9 @@ inline Status WriteSFixed32(int field_number, const DataPiece& data, } // Writes an SINT32 field, including tag, to the stream. -inline Status WriteSInt32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i32 = data.ToInt32(); +inline util::Status WriteSInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i32 = data.ToInt32(); if (i32.ok()) { WireFormatLite::WriteSInt32(field_number, i32.value(), stream); } @@ -150,9 +149,9 @@ inline Status WriteSInt32(int field_number, const DataPiece& data, } // Writes a FIXED32 field, including tag, to the stream. -inline Status WriteFixed32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr u32 = data.ToUint32(); +inline util::Status WriteFixed32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr u32 = data.ToUint32(); if (u32.ok()) { WireFormatLite::WriteFixed32(field_number, u32.value(), stream); } @@ -160,9 +159,9 @@ inline Status WriteFixed32(int field_number, const DataPiece& data, } // Writes a UINT32 field, including tag, to the stream. -inline Status WriteUInt32(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr u32 = data.ToUint32(); +inline util::Status WriteUInt32(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr u32 = data.ToUint32(); if (u32.ok()) { WireFormatLite::WriteUInt32(field_number, u32.value(), stream); } @@ -170,9 +169,9 @@ inline Status WriteUInt32(int field_number, const DataPiece& data, } // Writes an INT64 field, including tag, to the stream. -inline Status WriteInt64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i64 = data.ToInt64(); +inline util::Status WriteInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i64 = data.ToInt64(); if (i64.ok()) { WireFormatLite::WriteInt64(field_number, i64.value(), stream); } @@ -180,9 +179,9 @@ inline Status WriteInt64(int field_number, const DataPiece& data, } // Writes an SFIXED64 field, including tag, to the stream. -inline Status WriteSFixed64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i64 = data.ToInt64(); +inline util::Status WriteSFixed64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i64 = data.ToInt64(); if (i64.ok()) { WireFormatLite::WriteSFixed64(field_number, i64.value(), stream); } @@ -190,9 +189,9 @@ inline Status WriteSFixed64(int field_number, const DataPiece& data, } // Writes an SINT64 field, including tag, to the stream. -inline Status WriteSInt64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr i64 = data.ToInt64(); +inline util::Status WriteSInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr i64 = data.ToInt64(); if (i64.ok()) { WireFormatLite::WriteSInt64(field_number, i64.value(), stream); } @@ -200,9 +199,9 @@ inline Status WriteSInt64(int field_number, const DataPiece& data, } // Writes a FIXED64 field, including tag, to the stream. -inline Status WriteFixed64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr u64 = data.ToUint64(); +inline util::Status WriteFixed64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr u64 = data.ToUint64(); if (u64.ok()) { WireFormatLite::WriteFixed64(field_number, u64.value(), stream); } @@ -210,9 +209,9 @@ inline Status WriteFixed64(int field_number, const DataPiece& data, } // Writes a UINT64 field, including tag, to the stream. -inline Status WriteUInt64(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr u64 = data.ToUint64(); +inline util::Status WriteUInt64(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr u64 = data.ToUint64(); if (u64.ok()) { WireFormatLite::WriteUInt64(field_number, u64.value(), stream); } @@ -220,9 +219,9 @@ inline Status WriteUInt64(int field_number, const DataPiece& data, } // Writes a DOUBLE field, including tag, to the stream. -inline Status WriteDouble(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr d = data.ToDouble(); +inline util::Status WriteDouble(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr d = data.ToDouble(); if (d.ok()) { WireFormatLite::WriteDouble(field_number, d.value(), stream); } @@ -230,9 +229,9 @@ inline Status WriteDouble(int field_number, const DataPiece& data, } // Writes a FLOAT field, including tag, to the stream. -inline Status WriteFloat(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr f = data.ToFloat(); +inline util::Status WriteFloat(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr f = data.ToFloat(); if (f.ok()) { WireFormatLite::WriteFloat(field_number, f.value(), stream); } @@ -240,9 +239,9 @@ inline Status WriteFloat(int field_number, const DataPiece& data, } // Writes a BOOL field, including tag, to the stream. -inline Status WriteBool(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr b = data.ToBool(); +inline util::Status WriteBool(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr b = data.ToBool(); if (b.ok()) { WireFormatLite::WriteBool(field_number, b.value(), stream); } @@ -250,9 +249,9 @@ inline Status WriteBool(int field_number, const DataPiece& data, } // Writes a BYTES field, including tag, to the stream. -inline Status WriteBytes(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr c = data.ToBytes(); +inline util::Status WriteBytes(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr c = data.ToBytes(); if (c.ok()) { WireFormatLite::WriteBytes(field_number, c.ValueOrDie(), stream); } @@ -260,9 +259,9 @@ inline Status WriteBytes(int field_number, const DataPiece& data, } // Writes a STRING field, including tag, to the stream. -inline Status WriteString(int field_number, const DataPiece& data, - CodedOutputStream* stream) { - StatusOr s = data.ToString(); +inline util::Status WriteString(int field_number, const DataPiece& data, + CodedOutputStream* stream) { + util::StatusOr s = data.ToString(); if (s.ok()) { WireFormatLite::WriteString(field_number, s.value(), stream); } @@ -350,7 +349,9 @@ ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() { for (std::set::iterator it = required_fields_.begin(); it != required_fields_.end(); ++it) { - ow_->MissingField((*it)->name()); + ow_->MissingField(ow_->use_json_name_in_missing_fields_ + ? (*it)->json_name() + : (*it)->name()); } } // Computes the total number of proto bytes used by a message, also adjusts @@ -539,7 +540,7 @@ ProtoWriter* ProtoWriter::EndList() { ProtoWriter* ProtoWriter::RenderDataPiece( StringPiece name, const DataPiece& data) { - Status status; + util::Status status; if (invalid_depth_ > 0) return this; const google::protobuf::Field* field = Lookup(name); @@ -593,16 +594,16 @@ ProtoWriter* ProtoWriter::StartListField(const google::protobuf::Field& field, return this; } -Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data, - const google::protobuf::Enum* enum_type, - CodedOutputStream* stream, - bool use_lower_camel_for_enums, - bool case_insensitive_enum_parsing, - bool ignore_unknown_values) { +util::Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data, + const google::protobuf::Enum* enum_type, + CodedOutputStream* stream, + bool use_lower_camel_for_enums, + bool case_insensitive_enum_parsing, + bool ignore_unknown_values) { bool is_unknown_enum_value = false; - StatusOr e = data.ToEnum(enum_type, use_lower_camel_for_enums, - case_insensitive_enum_parsing, - ignore_unknown_values, &is_unknown_enum_value); + util::StatusOr e = data.ToEnum( + enum_type, use_lower_camel_for_enums, case_insensitive_enum_parsing, + ignore_unknown_values, &is_unknown_enum_value); if (e.ok() && !is_unknown_enum_value) { WireFormatLite::WriteEnum(field_number, e.value(), stream); } @@ -612,7 +613,7 @@ Status ProtoWriter::WriteEnum(int field_number, const DataPiece& data, ProtoWriter* ProtoWriter::RenderPrimitiveField( const google::protobuf::Field& field, const google::protobuf::Type& type, const DataPiece& data) { - Status status; + util::Status status; // Pushing a ProtoElement and then pop it off at the end for 2 purposes: // error location reporting and required field accounting. @@ -706,8 +707,8 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField( break; } default: // TYPE_GROUP or TYPE_MESSAGE - status = - Status(util::error::INVALID_ARGUMENT, data.ToString().value()); + status = util::Status(util::error::INVALID_ARGUMENT, + data.ToString().value()); } if (!status.ok()) { diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h index 7e79ce31e8..8149ed3624 100644 --- a/src/google/protobuf/util/internal/proto_writer.h +++ b/src/google/protobuf/util/internal/proto_writer.h @@ -159,6 +159,11 @@ class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { case_insensitive_enum_parsing_ = case_insensitive_enum_parsing; } + void set_use_json_name_in_missing_fields( + bool use_json_name_in_missing_fields) { + use_json_name_in_missing_fields_ = use_json_name_in_missing_fields; + } + protected: class PROTOBUF_EXPORT ProtoElement : public BaseElement, public LocationTrackerInterface { @@ -339,6 +344,9 @@ class PROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // If true, check if enum name in UPPER_CASE matches the field name. bool case_insensitive_enum_parsing_; + // If true, use the json name in missing fields errors. + bool use_json_name_in_missing_fields_; + // Variable for internal state processing: // element_ : the current element. // size_insert_: sizes of nested messages. diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 1a9cc9bf41..a941aa0988 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include @@ -59,7 +60,6 @@ namespace google { namespace protobuf { namespace util { using util::Status; -using util::StatusOr; namespace error { using util::error::Code; using util::error::INTERNAL; @@ -68,7 +68,6 @@ namespace converter { using ::PROTOBUF_NAMESPACE_ID::internal::WireFormat; using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; using util::Status; -using util::StatusOr; namespace { @@ -88,7 +87,7 @@ const google::protobuf::EnumValue* FindEnumValueByNumber( // Utility function to format nanos. const std::string FormatNanos(uint32 nanos, bool with_trailing_zeros); -StatusOr MapKeyDefaultValueAsString( +util::StatusOr MapKeyDefaultValueAsString( const google::protobuf::Field& field) { switch (field.kind()) { case google::protobuf::Field::TYPE_BOOL: @@ -107,7 +106,7 @@ StatusOr MapKeyDefaultValueAsString( case google::protobuf::Field::TYPE_STRING: return std::string(); default: - return Status(util::error::INTERNAL, "Invalid map key type."); + return util::Status(util::error::INTERNAL, "Invalid map key type."); } } } // namespace @@ -159,8 +158,8 @@ ProtoStreamObjectSource::~ProtoStreamObjectSource() { } } -Status ProtoStreamObjectSource::NamedWriteTo(StringPiece name, - ObjectWriter* ow) const { +util::Status ProtoStreamObjectSource::NamedWriteTo(StringPiece name, + ObjectWriter* ow) const { return WriteMessage(type_, name, 0, true, ow); } @@ -184,11 +183,9 @@ const google::protobuf::Field* ProtoStreamObjectSource::FindAndVerifyField( return field; } -Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, - StringPiece name, - const uint32 end_tag, - bool include_start_and_end, - ObjectWriter* ow) const { +util::Status ProtoStreamObjectSource::WriteMessage( + const google::protobuf::Type& type, StringPiece name, + const uint32 end_tag, bool include_start_and_end, ObjectWriter* ow) const { const TypeRenderer* type_renderer = FindTypeRenderer(type.name()); if (type_renderer != nullptr) { @@ -251,7 +248,7 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, return util::Status(); } -StatusOr ProtoStreamObjectSource::RenderList( +util::StatusOr ProtoStreamObjectSource::RenderList( const google::protobuf::Field* field, StringPiece name, uint32 list_tag, ObjectWriter* ow) const { uint32 tag_to_return = 0; @@ -273,7 +270,7 @@ StatusOr ProtoStreamObjectSource::RenderList( return tag_to_return; } -StatusOr ProtoStreamObjectSource::RenderMap( +util::StatusOr ProtoStreamObjectSource::RenderMap( const google::protobuf::Field* field, StringPiece name, uint32 list_tag, ObjectWriter* ow) const { const google::protobuf::Type* field_type = @@ -303,7 +300,8 @@ StatusOr ProtoStreamObjectSource::RenderMap( if (key_field == nullptr) { // The Type info for this map entry is incorrect. It should always // have a field named "key" and with field number 1. - return Status(util::error::INTERNAL, "Invalid map entry."); + return util::Status(util::error::INTERNAL, + "Invalid map entry."); } ASSIGN_OR_RETURN(map_key, MapKeyDefaultValueAsString(*key_field)); } @@ -311,7 +309,7 @@ StatusOr ProtoStreamObjectSource::RenderMap( } else { // The Type info for this map entry is incorrect. It should contain // exactly two fields with field number 1 and 2. - return Status(util::error::INTERNAL, "Invalid map entry."); + return util::Status(util::error::INTERNAL, "Invalid map entry."); } } stream_->PopLimit(old_limit); @@ -319,7 +317,7 @@ StatusOr ProtoStreamObjectSource::RenderMap( return tag_to_return; } -Status ProtoStreamObjectSource::RenderPacked( +util::Status ProtoStreamObjectSource::RenderPacked( const google::protobuf::Field* field, ObjectWriter* ow) const { uint32 length; stream_->ReadVarint32(&length); @@ -331,20 +329,21 @@ Status ProtoStreamObjectSource::RenderPacked( return util::Status(); } -Status ProtoStreamObjectSource::RenderTimestamp( +util::Status ProtoStreamObjectSource::RenderTimestamp( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { std::pair p = os->ReadSecondsAndNanos(type); int64 seconds = p.first; int32 nanos = p.second; if (seconds > kTimestampMaxSeconds || seconds < kTimestampMinSeconds) { - return Status(util::error::INTERNAL, - StrCat("Timestamp seconds exceeds limit for field: ", - field_name)); + return util::Status( + util::error::INTERNAL, + StrCat("Timestamp seconds exceeds limit for field: ", + field_name)); } if (nanos < 0 || nanos >= kNanosPerSecond) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Timestamp nanos exceeds limit for field: ", field_name)); } @@ -355,20 +354,20 @@ Status ProtoStreamObjectSource::RenderTimestamp( return util::Status(); } -Status ProtoStreamObjectSource::RenderDuration( +util::Status ProtoStreamObjectSource::RenderDuration( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { std::pair p = os->ReadSecondsAndNanos(type); int64 seconds = p.first; int32 nanos = p.second; if (seconds > kDurationMaxSeconds || seconds < kDurationMinSeconds) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Duration seconds exceeds limit for field: ", field_name)); } if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Duration nanos exceeds limit for field: ", field_name)); } @@ -376,7 +375,7 @@ Status ProtoStreamObjectSource::RenderDuration( std::string sign = ""; if (seconds < 0) { if (nanos > 0) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Duration nanos is non-negative, but seconds is " "negative for field: ", @@ -397,10 +396,9 @@ Status ProtoStreamObjectSource::RenderDuration( return util::Status(); } -Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderDouble( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint64 buffer64 = 0; // default value of Double wrapper value if (tag != 0) { @@ -411,10 +409,9 @@ Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderFloat( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32 = 0; // default value of Float wrapper value if (tag != 0) { @@ -425,10 +422,9 @@ Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderInt64( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint64 buffer64 = 0; // default value of Int64 wrapper value if (tag != 0) { @@ -439,10 +435,9 @@ Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderUInt64( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint64 buffer64 = 0; // default value of UInt64 wrapper value if (tag != 0) { @@ -453,10 +448,9 @@ Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderInt32( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32 = 0; // default value of Int32 wrapper value if (tag != 0) { @@ -467,10 +461,9 @@ Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderUInt32( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32 = 0; // default value of UInt32 wrapper value if (tag != 0) { @@ -481,10 +474,9 @@ Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderBool( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint64 buffer64 = 0; // results in 'false' value as default, which is the // default value of Bool wrapper @@ -496,10 +488,9 @@ Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderString( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32; std::string str; // default value of empty for String wrapper @@ -512,10 +503,9 @@ Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderBytes( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); uint32 buffer32; std::string str; @@ -528,10 +518,9 @@ Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderStruct( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { const google::protobuf::Field* field = nullptr; uint32 tag = os->stream_->ReadTag(); ow->StartObject(field_name); @@ -552,7 +541,7 @@ Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, return util::Status(); } -Status ProtoStreamObjectSource::RenderStructValue( +util::Status ProtoStreamObjectSource::RenderStructValue( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { const google::protobuf::Field* field = nullptr; @@ -569,7 +558,7 @@ Status ProtoStreamObjectSource::RenderStructValue( } // TODO(skarvaje): Avoid code duplication of for loops and SkipField logic. -Status ProtoStreamObjectSource::RenderStructListValue( +util::Status ProtoStreamObjectSource::RenderStructListValue( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { uint32 tag = os->stream_->ReadTag(); @@ -593,10 +582,9 @@ Status ProtoStreamObjectSource::RenderStructListValue( return util::Status(); } -Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, - const google::protobuf::Type& type, - StringPiece field_name, - ObjectWriter* ow) { +util::Status ProtoStreamObjectSource::RenderAny( + const ProtoStreamObjectSource* os, const google::protobuf::Type& type, + StringPiece field_name, ObjectWriter* ow) { // An Any is of the form { string type_url = 1; bytes value = 2; } uint32 tag; std::string type_url; @@ -676,7 +664,7 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, return result; } -Status ProtoStreamObjectSource::RenderFieldMask( +util::Status ProtoStreamObjectSource::RenderFieldMask( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { std::string combined; @@ -709,7 +697,7 @@ Status ProtoStreamObjectSource::RenderFieldMask( std::unordered_map* - ProtoStreamObjectSource::renderers_ = NULL; + ProtoStreamObjectSource::renderers_ = nullptr; PROTOBUF_NAMESPACE_ID::internal::once_flag source_renderers_init_; @@ -752,7 +740,7 @@ void ProtoStreamObjectSource::InitRendererMap() { void ProtoStreamObjectSource::DeleteRendererMap() { delete ProtoStreamObjectSource::renderers_; - renderers_ = NULL; + renderers_ = nullptr; } // static @@ -763,7 +751,7 @@ ProtoStreamObjectSource::FindTypeRenderer(const std::string& type_url) { return FindOrNull(*renderers_, type_url); } -Status ProtoStreamObjectSource::RenderField( +util::Status ProtoStreamObjectSource::RenderField( const google::protobuf::Field* field, StringPiece field_name, ObjectWriter* ow) const { // Short-circuit message types as it tends to call WriteMessage recursively @@ -777,7 +765,7 @@ Status ProtoStreamObjectSource::RenderField( const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(field->type_url()); if (type == nullptr) { - return Status( + return util::Status( util::error::INTERNAL, StrCat("Invalid configuration. Could not find the type: ", field->type_url())); @@ -795,8 +783,9 @@ Status ProtoStreamObjectSource::RenderField( --recursion_depth_; if (!stream_->ConsumedEntireMessage()) { - return Status(util::error::INVALID_ARGUMENT, - "Nested protocol message not parsed in its entirety."); + return util::Status( + util::error::INVALID_ARGUMENT, + "Nested protocol message not parsed in its entirety."); } stream_->PopLimit(old_limit); } else { @@ -806,7 +795,7 @@ Status ProtoStreamObjectSource::RenderField( return util::Status(); } -Status ProtoStreamObjectSource::RenderNonMessageField( +util::Status ProtoStreamObjectSource::RenderNonMessageField( const google::protobuf::Field* field, StringPiece field_name, ObjectWriter* ow) const { // Temporary buffers of different types. @@ -1091,10 +1080,10 @@ std::pair ProtoStreamObjectSource::ReadSecondsAndNanos( return std::pair(signed_seconds, signed_nanos); } -Status ProtoStreamObjectSource::IncrementRecursionDepth( +util::Status ProtoStreamObjectSource::IncrementRecursionDepth( StringPiece type_name, StringPiece field_name) const { if (++recursion_depth_ > max_recursion_depth_) { - return Status( + return util::Status( util::error::INVALID_ARGUMENT, StrCat("Message too deep. Max recursion depth reached for type '", type_name, "', field '", field_name, "'")); diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index 1343d9b3e6..9dce1187e0 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -179,8 +179,8 @@ class PROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // Returns the next tag after reading all map entries. The caller should use // this tag before reading more tags from the stream. util::StatusOr RenderMap(const google::protobuf::Field* field, - StringPiece name, uint32 list_tag, - ObjectWriter* ow) const; + StringPiece name, uint32 list_tag, + ObjectWriter* ow) const; // Renders a packed repeating field. A packed field is stored as: // {tag length item1 item2 item3} instead of the less efficient diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc index ab27349191..4c0caed356 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc @@ -106,11 +106,11 @@ class ProtostreamObjectSourceTest virtual ~ProtostreamObjectSourceTest() {} void DoTest(const Message& msg, const Descriptor* descriptor) { - Status status = ExecuteTest(msg, descriptor); + util::Status status = ExecuteTest(msg, descriptor); EXPECT_EQ(util::Status(), status); } - Status ExecuteTest(const Message& msg, const Descriptor* descriptor) { + util::Status ExecuteTest(const Message& msg, const Descriptor* descriptor) { std::ostringstream oss; msg.SerializePartialToOstream(&oss); std::string proto = oss.str(); @@ -596,7 +596,7 @@ TEST_P(ProtostreamObjectSourceTest, CyclicMessageDepthTest) { current = next; } - Status status = ExecuteTest(cyclic, Cyclic::descriptor()); + util::Status status = ExecuteTest(cyclic, Cyclic::descriptor()); EXPECT_EQ(util::error::INVALID_ARGUMENT, status.code()); } @@ -942,7 +942,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, MissingTypeUrlError) { // We start the "AnyOut" part and then fail when we hit the Any object. ow_.StartObject(""); - Status status = ExecuteTest(out, AnyOut::descriptor()); + util::Status status = ExecuteTest(out, AnyOut::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -958,7 +958,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeServiceError) { // We start the "AnyOut" part and then fail when we hit the Any object. ow_.StartObject(""); - Status status = ExecuteTest(out, AnyOut::descriptor()); + util::Status status = ExecuteTest(out, AnyOut::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -974,7 +974,7 @@ TEST_P(ProtostreamObjectSourceAnysTest, UnknownTypeError) { // We start the "AnyOut" part and then fail when we hit the Any object. ow_.StartObject(""); - Status status = ExecuteTest(out, AnyOut::descriptor()); + util::Status status = ExecuteTest(out, AnyOut::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -1107,7 +1107,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampBelowMinTest) { ts->set_seconds(kTimestampMinSeconds - 1); ow_.StartObject(""); - Status status = ExecuteTest(out, TimestampDuration::descriptor()); + util::Status status = ExecuteTest(out, TimestampDuration::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -1118,7 +1118,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidTimestampAboveMaxTest) { ts->set_seconds(kTimestampMaxSeconds + 1); ow_.StartObject(""); - Status status = ExecuteTest(out, TimestampDuration::descriptor()); + util::Status status = ExecuteTest(out, TimestampDuration::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -1129,7 +1129,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationBelowMinTest) { dur->set_seconds(kDurationMinSeconds - 1); ow_.StartObject(""); - Status status = ExecuteTest(out, TimestampDuration::descriptor()); + util::Status status = ExecuteTest(out, TimestampDuration::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } @@ -1140,7 +1140,7 @@ TEST_P(ProtostreamObjectSourceTimestampTest, InvalidDurationAboveMaxTest) { dur->set_seconds(kDurationMaxSeconds + 1); ow_.StartObject(""); - Status status = ExecuteTest(out, TimestampDuration::descriptor()); + util::Status status = ExecuteTest(out, TimestampDuration::descriptor()); EXPECT_EQ(util::error::INTERNAL, status.code()); } diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 817109b02d..ace209ab27 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -58,7 +58,6 @@ namespace converter { using ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite; using std::placeholders::_1; using util::Status; -using util::StatusOr; using util::error::INVALID_ARGUMENT; @@ -74,6 +73,7 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter( set_ignore_unknown_enum_values(options_.ignore_unknown_enum_values); set_use_lower_camel_for_enums(options_.use_lower_camel_for_enums); set_case_insensitive_enum_parsing(options_.case_insensitive_enum_parsing); + set_use_json_name_in_missing_fields(options.use_json_name_in_missing_fields); } ProtoStreamObjectWriter::ProtoStreamObjectWriter( @@ -87,6 +87,7 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter( set_ignore_unknown_fields(options_.ignore_unknown_fields); set_use_lower_camel_for_enums(options.use_lower_camel_for_enums); set_case_insensitive_enum_parsing(options_.case_insensitive_enum_parsing); + set_use_json_name_in_missing_fields(options.use_json_name_in_missing_fields); } ProtoStreamObjectWriter::ProtoStreamObjectWriter( @@ -329,7 +330,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { if (value.type() == DataPiece::TYPE_STRING) { type_url_ = std::string(value.str()); } else { - StatusOr s = value.ToString(); + util::StatusOr s = value.ToString(); if (!s.ok()) { parent_->InvalidValue("String", s.status().message()); invalid_ = true; @@ -338,7 +339,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { type_url_ = s.value(); } // Resolve the type url, and report an error if we failed to resolve it. - StatusOr resolved_type = + util::StatusOr resolved_type = parent_->typeinfo()->ResolveTypeUrl(type_url_); if (!resolved_type.ok()) { parent_->InvalidValue("Any", resolved_type.status().message()); @@ -643,6 +644,16 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( return this; } + if (field->kind() != google::protobuf::Field::TYPE_GROUP && + field->kind() != google::protobuf::Field::TYPE_MESSAGE) { + IncrementInvalidDepth(); + if (!options_.suppress_object_to_scalar_error) { + InvalidValue(field->name(), "Starting an object on a scalar field"); + } + + return this; + } + // A regular message type. Pass it directly to ProtoWriter. // Render // "": { @@ -910,7 +921,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, switch (data.type()) { case DataPiece::TYPE_INT32: { if (ow->options_.struct_integers_as_strings) { - StatusOr int_value = data.ToInt32(); + util::StatusOr int_value = data.ToInt32(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", @@ -923,7 +934,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, } case DataPiece::TYPE_UINT32: { if (ow->options_.struct_integers_as_strings) { - StatusOr int_value = data.ToUint32(); + util::StatusOr int_value = data.ToUint32(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", @@ -938,7 +949,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, // If the option to treat integers as strings is set, then render them as // strings. Otherwise, fallback to rendering them as double. if (ow->options_.struct_integers_as_strings) { - StatusOr int_value = data.ToInt64(); + util::StatusOr int_value = data.ToInt64(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", DataPiece(StrCat(int_value.value()), true)); @@ -952,7 +963,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, // If the option to treat integers as strings is set, then render them as // strings. Otherwise, fallback to rendering them as double. if (ow->options_.struct_integers_as_strings) { - StatusOr int_value = data.ToUint64(); + util::StatusOr int_value = data.ToUint64(); if (int_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", DataPiece(StrCat(int_value.value()), true)); @@ -964,7 +975,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, } case DataPiece::TYPE_FLOAT: { if (ow->options_.struct_integers_as_strings) { - StatusOr float_value = data.ToFloat(); + util::StatusOr float_value = data.ToFloat(); if (float_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", @@ -977,7 +988,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, } case DataPiece::TYPE_DOUBLE: { if (ow->options_.struct_integers_as_strings) { - StatusOr double_value = data.ToDouble(); + util::StatusOr double_value = data.ToDouble(); if (double_value.ok()) { ow->ProtoWriter::RenderDataPiece( "string_value", @@ -1035,7 +1046,7 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, } static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow, - StringPiece path) { + StringPiece path) { ow->ProtoWriter::RenderDataPiece( "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true)); return Status(); diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h index cc68c6b1b4..a5bea409d1 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.h +++ b/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -107,6 +107,13 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { // is disabled. bool suppress_implicit_message_list_error; + // If true, suppress the error of rendering scalar field if the source is an + // object. + bool suppress_object_to_scalar_error; + + // If true, use the json name in missing fields errors. + bool use_json_name_in_missing_fields; + Options() : struct_integers_as_strings(false), ignore_unknown_fields(false), @@ -116,7 +123,9 @@ class PROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { ignore_null_value_map_entry(false), use_legacy_json_map_format(false), disable_implicit_message_list(false), - suppress_implicit_message_list_error(false) {} + suppress_implicit_message_list_error(false), + suppress_object_to_scalar_error(false), + use_json_name_in_missing_fields(false) {} // Default instance of Options with all options set to defaults. static const Options& Defaults() { diff --git a/src/google/protobuf/util/internal/structured_objectwriter.h b/src/google/protobuf/util/internal/structured_objectwriter.h index bccea718c4..01cbb9e1ac 100644 --- a/src/google/protobuf/util/internal/structured_objectwriter.h +++ b/src/google/protobuf/util/internal/structured_objectwriter.h @@ -69,7 +69,8 @@ class PROTOBUF_EXPORT StructuredObjectWriter : public ObjectWriter { public: // Takes ownership of the parent Element. explicit BaseElement(BaseElement* parent) - : parent_(parent), level_(parent == NULL ? 0 : parent->level() + 1) {} + : parent_(parent), + level_(parent == nullptr ? 0 : parent->level() + 1) {} virtual ~BaseElement() {} // Releases ownership of the parent and returns a pointer to it. diff --git a/src/google/protobuf/util/internal/type_info_test_helper.cc b/src/google/protobuf/util/internal/type_info_test_helper.cc index cc2dcd73cb..ccf6fbd836 100644 --- a/src/google/protobuf/util/internal/type_info_test_helper.cc +++ b/src/google/protobuf/util/internal/type_info_test_helper.cc @@ -95,7 +95,7 @@ ProtoStreamObjectSource* TypeInfoTestHelper::NewProtoSource( } } GOOGLE_LOG(FATAL) << "Can not reach here."; - return NULL; + return nullptr; } ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter( @@ -109,7 +109,7 @@ ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter( } } GOOGLE_LOG(FATAL) << "Can not reach here."; - return NULL; + return nullptr; } DefaultValueObjectWriter* TypeInfoTestHelper::NewDefaultValueWriter( @@ -121,7 +121,7 @@ DefaultValueObjectWriter* TypeInfoTestHelper::NewDefaultValueWriter( } } GOOGLE_LOG(FATAL) << "Can not reach here."; - return NULL; + return nullptr; } } // namespace testing diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index 84682fa4d5..1816b6843f 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -330,7 +330,7 @@ std::string ToSnakeCase(StringPiece input) { return result; } -std::set* well_known_types_ = NULL; +std::set* well_known_types_ = nullptr; PROTOBUF_NAMESPACE_ID::internal::once_flag well_known_types_init_; const char* well_known_types_name_array_[] = { "google.protobuf.Timestamp", "google.protobuf.Duration", diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 9bfe0dd67e..1388e9d33a 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -919,7 +919,8 @@ bool MessageDifferencer::IsMatch( bool MessageDifferencer::CompareMapFieldByMapReflection( const Message& message1, const Message& message2, - const FieldDescriptor* map_field) { + const FieldDescriptor* map_field, std::vector* parent_fields, + DefaultFieldComparator* comparator) { const Reflection* reflection1 = message1.GetReflection(); const Reflection* reflection2 = message2.GetReflection(); const int count1 = reflection1->MapSize(message1, map_field); @@ -945,9 +946,9 @@ bool MessageDifferencer::CompareMapFieldByMapReflection( } \ MapValueConstRef value2; \ reflection2->LookupMapValue(message2, map_field, it.GetKey(), &value2); \ - if (!default_field_comparator_.Compare##COMPAREMETHOD( \ - *val_des, it.GetValueRef().Get##METHOD(), \ - value2.Get##METHOD())) { \ + if (!comparator->Compare##COMPAREMETHOD(*val_des, \ + it.GetValueRef().Get##METHOD(), \ + value2.Get##METHOD())) { \ return false; \ } \ } \ @@ -972,10 +973,17 @@ bool MessageDifferencer::CompareMapFieldByMapReflection( if (!reflection2->ContainsMapKey(message2, map_field, it.GetKey())) { return false; } + bool compare_result; MapValueConstRef value2; reflection2->LookupMapValue(message2, map_field, it.GetKey(), &value2); - if (!Compare(it.GetValueRef().GetMessageValue(), - value2.GetMessageValue())) { + // Append currently compared field to the end of parent_fields. + SpecificField specific_value_field; + specific_value_field.field = val_des; + parent_fields->push_back(specific_value_field); + compare_result = Compare(it.GetValueRef().GetMessageValue(), + value2.GetMessageValue(), parent_fields); + parent_fields->pop_back(); + if (!compare_result) { return false; } } @@ -996,18 +1004,42 @@ bool MessageDifferencer::CompareRepeatedField( // When both map fields are on map, do not sync to repeated field. // TODO(jieluo): Add support for reporter if (repeated_field->is_map() && reporter_ == nullptr && - field_comparator_ == nullptr) { - const FieldDescriptor* key_des = repeated_field->message_type()->map_key(); - const FieldDescriptor* val_des = - repeated_field->message_type()->map_value(); - const internal::MapFieldBase* map_field1 = - reflection1->GetMapData(message1, repeated_field); - const internal::MapFieldBase* map_field2 = - reflection2->GetMapData(message2, repeated_field); - if (map_field1->IsMapValid() && map_field2->IsMapValid() && - ignored_fields_.find(key_des) == ignored_fields_.end() && - ignored_fields_.find(val_des) == ignored_fields_.end()) { - return CompareMapFieldByMapReflection(message1, message2, repeated_field); + // Users didn't set custom map field key comparator + map_field_key_comparator_.find(repeated_field) == + map_field_key_comparator_.end() && + // Users didn't set repeated field comparison + repeated_field_comparison_ == AS_LIST) { + DefaultFieldComparator* map_field_comparator = + field_comparator_ ? nullptr : &default_field_comparator_; +#if PROTOBUF_RTTI + // Inherit class from DefaultFieldComparator can not get the benefit + // because DefaultFieldComparator::Compare() method might be overwrote. + if (field_comparator_ && + typeid(*field_comparator_) == typeid(default_field_comparator_)) { + map_field_comparator = + static_cast(field_comparator_); + } +#endif + if (map_field_comparator) { + const FieldDescriptor* key_des = + repeated_field->message_type()->map_key(); + const FieldDescriptor* val_des = + repeated_field->message_type()->map_value(); + const internal::MapFieldBase* map_field1 = + reflection1->GetMapData(message1, repeated_field); + const internal::MapFieldBase* map_field2 = + reflection2->GetMapData(message2, repeated_field); + std::vector current_parent_fields(*parent_fields); + SpecificField specific_field; + specific_field.field = repeated_field; + current_parent_fields.push_back(specific_field); + if (map_field1->IsMapValid() && map_field2->IsMapValid() && + !IsIgnored(message1, message2, key_des, current_parent_fields) && + !IsIgnored(message1, message2, val_des, current_parent_fields)) { + return CompareMapFieldByMapReflection( + message1, message2, repeated_field, ¤t_parent_fields, + map_field_comparator); + } } } diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index 943fadf145..2384e51d39 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h @@ -760,7 +760,9 @@ class PROTOBUF_EXPORT MessageDifferencer { // Compare the map fields using map reflection instead of sync to repeated. bool CompareMapFieldByMapReflection(const Message& message1, const Message& message2, - const FieldDescriptor* field); + const FieldDescriptor* field, + std::vector* parent_fields, + DefaultFieldComparator* comparator); // Shorthand for CompareFieldValueUsingParentFields with NULL parent_fields. bool CompareFieldValue(const Message& message1, const Message& message2, diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index 21debfcb80..ef86a350ea 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -1668,7 +1668,7 @@ StringValue::StringValue(const StringValue& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_value().empty()) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_value(), + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.StringValue) @@ -1711,7 +1711,7 @@ void StringValue::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + value_.ClearToEmpty(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } @@ -1875,7 +1875,7 @@ BytesValue::BytesValue(const BytesValue& from) _internal_metadata_.MergeFrom<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(from._internal_metadata_); value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited()); if (!from._internal_value().empty()) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from._internal_value(), + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, from._internal_value(), GetArena()); } // @@protoc_insertion_point(copy_constructor:google.protobuf.BytesValue) @@ -1918,7 +1918,7 @@ void BytesValue::Clear() { // Prevent compiler warnings about cached_has_bits being unused (void) cached_has_bits; - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + value_.ClearToEmpty(); _internal_metadata_.Clear<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(); } diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 5a092cd2e8..356e60e8fa 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -1515,7 +1514,7 @@ inline void BoolValue::set_value(bool value) { // string value = 1; inline void StringValue::clear_value() { - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + value_.ClearToEmpty(); } inline const std::string& StringValue::value() const { // @@protoc_insertion_point(field_get:google.protobuf.StringValue.value) @@ -1534,31 +1533,30 @@ inline const std::string& StringValue::_internal_value() const { } inline void StringValue::_internal_set_value(const std::string& value) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void StringValue::set_value(std::string&& value) { value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.StringValue.value) } inline void StringValue::set_value(const char* value) { GOOGLE_DCHECK(value != nullptr); - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.StringValue.value) } inline void StringValue::set_value(const char* value, size_t size) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.StringValue.value) } inline std::string* StringValue::_internal_mutable_value() { - return value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* StringValue::release_value() { // @@protoc_insertion_point(field_release:google.protobuf.StringValue.value) @@ -1581,7 +1579,7 @@ inline void StringValue::set_allocated_value(std::string* value) { // bytes value = 1; inline void BytesValue::clear_value() { - value_.ClearToEmpty(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + value_.ClearToEmpty(); } inline const std::string& BytesValue::value() const { // @@protoc_insertion_point(field_get:google.protobuf.BytesValue.value) @@ -1600,31 +1598,30 @@ inline const std::string& BytesValue::_internal_value() const { } inline void BytesValue::_internal_set_value(const std::string& value) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), value, GetArena()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, value, GetArena()); } inline void BytesValue::set_value(std::string&& value) { value_.Set( - &::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::move(value), GetArena()); + ::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::move(value), GetArena()); // @@protoc_insertion_point(field_set_rvalue:google.protobuf.BytesValue.value) } inline void BytesValue::set_value(const char* value) { GOOGLE_DCHECK(value != nullptr); - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string(value), - GetArena()); + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string(value), GetArena()); // @@protoc_insertion_point(field_set_char:google.protobuf.BytesValue.value) } inline void BytesValue::set_value(const void* value, size_t size) { - value_.Set(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), ::std::string( + value_.Set(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, ::std::string( reinterpret_cast(value), size), GetArena()); // @@protoc_insertion_point(field_set_pointer:google.protobuf.BytesValue.value) } inline std::string* BytesValue::_internal_mutable_value() { - return value_.Mutable(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), GetArena()); + return value_.Mutable(::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr::EmptyDefault{}, GetArena()); } inline std::string* BytesValue::release_value() { // @@protoc_insertion_point(field_release:google.protobuf.BytesValue.value) diff --git a/tests.sh b/tests.sh index 3d47b6cbf2..8b499d0a3e 100755 --- a/tests.sh +++ b/tests.sh @@ -64,7 +64,7 @@ build_cpp_distcheck() { git ls-files | grep "^\(java\|python\|objectivec\|csharp\|js\|ruby\|php\|cmake\|examples\|src/google/protobuf/.*\.proto\)" |\ grep -v ".gitignore" | grep -v "java/compatibility_tests" | grep -v "java/lite/proguard.pgcfg" |\ grep -v "python/compatibility_tests" | grep -v "python/docs" | grep -v "python/.repo-metadata.json" |\ - grep -v "csharp/compatibility_tests" > dist.lst + grep -v "python/protobuf_distutils" | grep -v "csharp/compatibility_tests" > dist.lst # Unzip the dist tar file. DIST=`ls *.tar.gz` tar -xf $DIST