From 0400cca3236de1ca303af38bf81eab332d042b7c Mon Sep 17 00:00:00 2001 From: Adam Cozzette Date: Tue, 13 Mar 2018 16:37:29 -0700 Subject: Integrated internal changes from Google --- src/google/protobuf/util/field_mask_util.cc | 27 ++++--- src/google/protobuf/util/field_mask_util.h | 4 +- src/google/protobuf/util/field_mask_util_test.cc | 13 +++- src/google/protobuf/util/internal/datapiece.cc | 20 +++--- .../util/internal/default_value_objectwriter.cc | 84 +++++++++++----------- .../util/internal/default_value_objectwriter.h | 9 +-- .../internal/default_value_objectwriter_test.cc | 4 +- src/google/protobuf/util/internal/error_listener.h | 3 - .../protobuf/util/internal/field_mask_utility.cc | 3 +- .../protobuf/util/internal/json_objectwriter.h | 7 +- .../util/internal/json_objectwriter_test.cc | 2 +- .../protobuf/util/internal/json_stream_parser.cc | 5 +- src/google/protobuf/util/internal/proto_writer.cc | 62 ++++++++-------- src/google/protobuf/util/internal/proto_writer.h | 44 ++++++------ .../util/internal/protostream_objectsource.cc | 69 +++++++++--------- .../util/internal/protostream_objectsource_test.cc | 27 +++++-- .../util/internal/protostream_objectwriter.cc | 78 ++++++++++---------- .../util/internal/protostream_objectwriter.h | 8 +-- .../util/internal/protostream_objectwriter_test.cc | 8 +-- .../util/internal/structured_objectwriter.h | 9 +-- .../protobuf/util/internal/testdata/books.proto | 1 + src/google/protobuf/util/internal/type_info.cc | 4 +- .../util/internal/type_info_test_helper.cc | 3 - .../protobuf/util/internal/type_info_test_helper.h | 7 +- src/google/protobuf/util/internal/utility.cc | 48 ++++++++----- src/google/protobuf/util/internal/utility.h | 22 +++--- src/google/protobuf/util/json_util.cc | 8 +-- src/google/protobuf/util/json_util_test.cc | 28 ++++---- src/google/protobuf/util/message_differencer.cc | 31 +++++--- src/google/protobuf/util/message_differencer.h | 10 ++- .../protobuf/util/message_differencer_unittest.cc | 21 ++++++ src/google/protobuf/util/time_util.cc | 5 +- src/google/protobuf/util/type_resolver_util.cc | 8 +-- .../protobuf/util/type_resolver_util_test.cc | 26 ++++--- 34 files changed, 386 insertions(+), 322 deletions(-) (limited to 'src/google/protobuf/util') diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc index 8a413498..a2e2a388 100644 --- a/src/google/protobuf/util/field_mask_util.cc +++ b/src/google/protobuf/util/field_mask_util.cc @@ -31,6 +31,7 @@ #include #include + #include namespace google { @@ -131,27 +132,27 @@ bool FieldMaskUtil::FromJsonString(StringPiece str, FieldMask* out) { bool FieldMaskUtil::GetFieldDescriptors( const Descriptor* descriptor, StringPiece path, std::vector* field_descriptors) { - if (field_descriptors != NULL) { + if (field_descriptors != nullptr) { field_descriptors->clear(); } std::vector parts = Split(path, "."); for (int i = 0; i < parts.size(); ++i) { const string& field_name = parts[i]; - if (descriptor == NULL) { + if (descriptor == nullptr) { return false; } const FieldDescriptor* field = descriptor->FindFieldByName(field_name); - if (field == NULL) { + if (field == nullptr) { return false; } - if (field_descriptors != NULL) { + if (field_descriptors != nullptr) { field_descriptors->push_back(field); } if (!field->is_repeated() && field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { descriptor = field->message_type(); } else { - descriptor = NULL; + descriptor = nullptr; } } return true; @@ -342,6 +343,12 @@ void FieldMaskTree::AddPath(const string& path) { void FieldMaskTree::RemovePath(const string& path, const Descriptor* descriptor) { + if (root_.children.empty()) { + // Nothing to be removed from an empty tree. We shortcut it here so an empty + // tree won't be interpreted as a field mask containing all fields by the + // code below. + return; + } std::vector parts = Split(path, "."); if (parts.empty()) { return; @@ -349,16 +356,16 @@ void FieldMaskTree::RemovePath(const string& path, std::vector nodes(parts.size()); Node* node = &root_; const Descriptor* current_descriptor = descriptor; - Node* new_branch_node = NULL; + Node* new_branch_node = nullptr; for (int i = 0; i < parts.size(); ++i) { nodes[i] = node; const FieldDescriptor* field_descriptor = current_descriptor->FindFieldByName(parts[i]); - if (field_descriptor == NULL || + if (field_descriptor == nullptr || (field_descriptor->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE && i != parts.size() - 1)) { // Invalid path. - if (new_branch_node != NULL) { + if (new_branch_node != nullptr) { // If add any new nodes, cleanup. new_branch_node->ClearChildren(); } @@ -366,7 +373,7 @@ void FieldMaskTree::RemovePath(const string& path, } if (node->children.empty()) { - if (new_branch_node == NULL) { + if (new_branch_node == nullptr) { new_branch_node = node; } for (int i = 0; i < current_descriptor->field_count(); ++i) { @@ -542,7 +549,7 @@ void FieldMaskTree::AddRequiredFieldPath( if (field->is_required()) { const string& node_name = field->name(); Node*& child = node->children[node_name]; - if (child == NULL) { + if (child == nullptr) { // Add required field path to the tree child = new Node(); } else if (child->children.empty()){ diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h index 91787bd5..f0299de9 100644 --- a/src/google/protobuf/util/field_mask_util.h +++ b/src/google/protobuf/util/field_mask_util.h @@ -70,14 +70,14 @@ class LIBPROTOBUF_EXPORT FieldMaskUtil { // Checks whether the given path is valid for type T. template static bool IsValidPath(StringPiece path) { - return GetFieldDescriptors(T::descriptor(), path, NULL); + return GetFieldDescriptors(T::descriptor(), path, nullptr); } // Checks whether the given FieldMask is valid for type T. template static bool IsValidFieldMask(const FieldMask& mask) { for (int i = 0; i < mask.paths_size(); ++i) { - if (!GetFieldDescriptors(T::descriptor(), mask.paths(i), NULL)) + if (!GetFieldDescriptors(T::descriptor(), mask.paths(i), nullptr)) return false; } return true; diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc index 0664d9e5..3ba30aa3 100644 --- a/src/google/protobuf/util/field_mask_util_test.cc +++ b/src/google/protobuf/util/field_mask_util_test.cc @@ -168,7 +168,7 @@ TEST(FieldMaskUtilTest, GetFieldDescriptors) { EXPECT_EQ(1, field_descriptors.size()); EXPECT_EQ("optional_int32", field_descriptors[0]->name()); EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors( - TestAllTypes::descriptor(), "optional_nonexist", NULL)); + TestAllTypes::descriptor(), "optional_nonexist", nullptr)); EXPECT_TRUE(FieldMaskUtil::GetFieldDescriptors(TestAllTypes::descriptor(), "optional_nested_message.bb", &field_descriptors)); @@ -176,10 +176,10 @@ TEST(FieldMaskUtilTest, GetFieldDescriptors) { EXPECT_EQ("optional_nested_message", field_descriptors[0]->name()); EXPECT_EQ("bb", field_descriptors[1]->name()); EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors( - TestAllTypes::descriptor(), "optional_nested_message.nonexist", NULL)); + TestAllTypes::descriptor(), "optional_nested_message.nonexist", nullptr)); // FieldMask cannot be used to specify sub-fields of a repeated message. EXPECT_FALSE(FieldMaskUtil::GetFieldDescriptors( - TestAllTypes::descriptor(), "repeated_nested_message.bb", NULL)); + TestAllTypes::descriptor(), "repeated_nested_message.bb", nullptr)); } TEST(FieldMaskUtilTest, TestIsVaildPath) { @@ -386,6 +386,13 @@ TEST(FieldMaskUtilTest, TestSubtract) { FieldMaskUtil::FromString("optional_nested_message", &mask2); FieldMaskUtil::Subtract(mask1, mask2, &out); EXPECT_EQ("", FieldMaskUtil::ToString(out)); + + // Regression test for b/72727550 + FieldMaskUtil::FromString("optional_foreign_message.c", &mask1); + FieldMaskUtil::FromString("optional_foreign_message,optional_nested_message", + &mask2); + FieldMaskUtil::Subtract(mask1, mask2, &out); + EXPECT_EQ("", FieldMaskUtil::ToString(out)); } TEST(FieldMaskUtilTest, TestIspathInFieldMask) { diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc index 213c2c40..2f4242d5 100644 --- a/src/google/protobuf/util/internal/datapiece.cc +++ b/src/google/protobuf/util/internal/datapiece.cc @@ -64,9 +64,9 @@ StatusOr ValidateNumberConversion(To after, From before) { MathUtil::Sign(before) == MathUtil::Sign(after)) { return after; } else { - return InvalidArgument(::google::protobuf::internal::is_integral::value + return InvalidArgument(std::is_integral::value ? ValueAsString(before) - : ::google::protobuf::internal::is_same::value + : std::is_same::value ? DoubleAsString(before) : FloatAsString(before)); } @@ -77,7 +77,7 @@ StatusOr ValidateNumberConversion(To after, From before) { // except conversion between double and float. template StatusOr NumberConvertAndCheck(From before) { - if (::google::protobuf::internal::is_same::value) return before; + if (std::is_same::value) return before; To after = static_cast(before); return ValidateNumberConversion(after, before); @@ -87,7 +87,7 @@ StatusOr NumberConvertAndCheck(From before) { // point types (double, float) only. template StatusOr FloatingPointToIntConvertAndCheck(From before) { - if (::google::protobuf::internal::is_same::value) return before; + if (std::is_same::value) return before; To after = static_cast(before); return ValidateNumberConversion(after, before); @@ -280,7 +280,7 @@ StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, string enum_name = str_.ToString(); const google::protobuf::EnumValue* value = FindEnumValueByNameOrNull(enum_type, enum_name); - if (value != NULL) return value->number(); + if (value != nullptr) return value->number(); // Check if int version of enum is sent as string. StatusOr int_value = ToInt32(); @@ -296,14 +296,14 @@ StatusOr DataPiece::ToEnum(const google::protobuf::Enum* enum_type, *it = *it == '-' ? '_' : ascii_toupper(*it); } value = FindEnumValueByNameOrNull(enum_type, enum_name); - if (value != NULL) return value->number(); + if (value != nullptr) return value->number(); // If use_lower_camel_for_enums is true try with enum name without // underscore. This will also accept camel case names as the enum_name has // been normalized before. if (use_lower_camel_for_enums) { value = FindEnumValueByNameWithoutUnderscoreOrNull(enum_type, enum_name); - if (value != NULL) return value->number(); + if (value != nullptr) return value->number(); } } else { // We don't need to check whether the value is actually declared in the @@ -357,7 +357,8 @@ bool DataPiece::DecodeBase64(StringPiece src, string* dest) const { WebSafeBase64Escape(*dest, &encoded); // Remove trailing padding '=' characters before comparison. StringPiece src_no_padding = StringPiece(src).substr( - 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length()); + 0, StringEndsWith(src, "=") ? src.find_last_not_of('=') + 1 + : src.length()); return encoded == src_no_padding; } return true; @@ -370,7 +371,8 @@ bool DataPiece::DecodeBase64(StringPiece src, string* dest) const { reinterpret_cast(dest->data()), dest->length(), &encoded, false); StringPiece src_no_padding = StringPiece(src).substr( - 0, src.ends_with("=") ? src.find_last_not_of('=') + 1 : src.length()); + 0, StringEndsWith(src, "=") ? src.find_last_not_of('=') + 1 + : src.length()); return encoded == src_no_padding; } return true; diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index 95b3a17d..2826e90e 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -62,11 +62,11 @@ DefaultValueObjectWriter::DefaultValueObjectWriter( : typeinfo_(TypeInfo::NewTypeInfo(type_resolver)), own_typeinfo_(true), type_(type), - current_(NULL), - root_(NULL), + current_(nullptr), + root_(nullptr), suppress_empty_list_(false), preserve_proto_field_names_(false), - field_scrub_callback_(NULL), + field_scrub_callback_(nullptr), ow_(ow) {} DefaultValueObjectWriter::~DefaultValueObjectWriter() { @@ -80,7 +80,7 @@ DefaultValueObjectWriter::~DefaultValueObjectWriter() { DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBool(StringPiece name, bool value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderBool(name, value); } else { RenderDataPiece(name, DataPiece(value)); @@ -90,7 +90,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBool(StringPiece name, DefaultValueObjectWriter* DefaultValueObjectWriter::RenderInt32( StringPiece name, int32 value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderInt32(name, value); } else { RenderDataPiece(name, DataPiece(value)); @@ -100,7 +100,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderInt32( DefaultValueObjectWriter* DefaultValueObjectWriter::RenderUint32( StringPiece name, uint32 value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderUint32(name, value); } else { RenderDataPiece(name, DataPiece(value)); @@ -110,7 +110,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderUint32( DefaultValueObjectWriter* DefaultValueObjectWriter::RenderInt64( StringPiece name, int64 value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderInt64(name, value); } else { RenderDataPiece(name, DataPiece(value)); @@ -120,7 +120,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderInt64( DefaultValueObjectWriter* DefaultValueObjectWriter::RenderUint64( StringPiece name, uint64 value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderUint64(name, value); } else { RenderDataPiece(name, DataPiece(value)); @@ -130,7 +130,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderUint64( DefaultValueObjectWriter* DefaultValueObjectWriter::RenderDouble( StringPiece name, double value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderDouble(name, value); } else { RenderDataPiece(name, DataPiece(value)); @@ -140,7 +140,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderDouble( DefaultValueObjectWriter* DefaultValueObjectWriter::RenderFloat( StringPiece name, float value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderBool(name, value); } else { RenderDataPiece(name, DataPiece(value)); @@ -150,7 +150,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderFloat( DefaultValueObjectWriter* DefaultValueObjectWriter::RenderString( StringPiece name, StringPiece value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderString(name, value); } else { // Since StringPiece is essentially a pointer, takes a copy of "value" to @@ -163,7 +163,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderString( DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBytes( StringPiece name, StringPiece value) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderBytes(name, value); } else { // Since StringPiece is essentially a pointer, takes a copy of "value" to @@ -176,7 +176,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBytes( DefaultValueObjectWriter* DefaultValueObjectWriter::RenderNull( StringPiece name) { - if (current_ == NULL) { + if (current_ == nullptr) { ow_->RenderNull(name); } else { RenderDataPiece(name, DataPiece::NullData()); @@ -241,7 +241,7 @@ DefaultValueObjectWriter::Node::Node( DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild( StringPiece name) { if (name.empty() || kind_ != OBJECT) { - return NULL; + return nullptr; } for (int i = 0; i < children_.size(); ++i) { Node* child = children_[i]; @@ -249,7 +249,7 @@ DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild( return child; } } - return NULL; + return nullptr; } void DefaultValueObjectWriter::Node::WriteTo(ObjectWriter* ow) { @@ -317,7 +317,7 @@ const google::protobuf::Type* DefaultValueObjectWriter::Node::GetMapValueType( } break; } - return NULL; + return nullptr; } void DefaultValueObjectWriter::Node::PopulateChildren( @@ -328,7 +328,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren( // TODO(tsun): remove "kStructValueType" from the list. It's being checked // now because of a bug in the tool-chain that causes the "oneof_index" // of kStructValueType to not be set correctly. - if (type_ == NULL || type_->name() == kAnyType || + if (type_ == nullptr || type_->name() == kAnyType || type_->name() == kStructType || type_->name() == kTimestampType || type_->name() == kDurationType || type_->name() == kStructValueType) { return; @@ -351,7 +351,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren( path.insert(path.begin(), path_.begin(), path_.end()); } path.push_back(field.name()); - if (field_scrub_callback_ != NULL && + if (field_scrub_callback_ != nullptr && field_scrub_callback_->Run(path, &field)) { continue; } @@ -362,11 +362,11 @@ void DefaultValueObjectWriter::Node::PopulateChildren( // of children. if (found != orig_children_map.end()) { new_children.push_back(children_[found->second]); - children_[found->second] = NULL; + children_[found->second] = nullptr; continue; } - const google::protobuf::Type* field_type = NULL; + const google::protobuf::Type* field_type = nullptr; bool is_map = false; NodeKind kind = PRIMITIVE; @@ -405,7 +405,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren( // If the child field is of primitive type, sets its data to the default // value of its type. - google::protobuf::scoped_ptr child(new Node( + std::unique_ptr child(new Node( preserve_proto_field_names_ ? field.name() : field.json_name(), field_type, kind, kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo) @@ -416,11 +416,11 @@ void DefaultValueObjectWriter::Node::PopulateChildren( } // Adds all leftover nodes in children_ to the beginning of new_child. for (int i = 0; i < children_.size(); ++i) { - if (children_[i] == NULL) { + if (children_[i] == nullptr) { continue; } new_children.insert(new_children.begin(), children_[i]); - children_[i] = NULL; + children_[i] = nullptr; } children_.swap(new_children); } @@ -428,7 +428,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren( void DefaultValueObjectWriter::MaybePopulateChildrenOfAny(Node* node) { // If this is an "Any" node with "@type" already given and no other children // have been added, populates its children. - if (node != NULL && node->is_any() && node->type() != NULL && + if (node != nullptr && node->is_any() && node->type() != nullptr && node->type()->name() != kAnyType && node->number_of_children() == 1) { node->PopulateChildren(typeinfo_); } @@ -504,7 +504,7 @@ DataPiece DefaultValueObjectWriter::CreateDefaultDataPieceForField( DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( StringPiece name) { - if (current_ == NULL) { + if (current_ == nullptr) { std::vector path; root_.reset(CreateNewNode(string(name), &type_, OBJECT, DataPiece::NullData(), false, path, @@ -516,16 +516,16 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( } MaybePopulateChildrenOfAny(current_); Node* child = current_->FindChild(name); - if (current_->kind() == LIST || current_->kind() == MAP || child == NULL) { + if (current_->kind() == LIST || current_->kind() == MAP || child == nullptr) { // If current_ is a list or a map node, we should create a new child and use // the type of current_ as the type of the new child. - google::protobuf::scoped_ptr node( + std::unique_ptr node( CreateNewNode(string(name), ((current_->kind() == LIST || current_->kind() == MAP) ? current_->type() - : NULL), + : nullptr), OBJECT, DataPiece::NullData(), false, - child == NULL ? current_->path() : child->path(), + child == nullptr ? current_->path() : child->path(), suppress_empty_list_, preserve_proto_field_names_, field_scrub_callback_.get())); child = node.get(); @@ -555,7 +555,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::EndObject() { DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( StringPiece name) { - if (current_ == NULL) { + if (current_ == nullptr) { std::vector path; root_.reset(CreateNewNode(string(name), &type_, LIST, DataPiece::NullData(), false, path, suppress_empty_list_, @@ -566,10 +566,10 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( } MaybePopulateChildrenOfAny(current_); Node* child = current_->FindChild(name); - if (child == NULL || child->kind() != LIST) { - google::protobuf::scoped_ptr node( - CreateNewNode(string(name), NULL, LIST, DataPiece::NullData(), false, - child == NULL ? current_->path() : child->path(), + if (child == nullptr || child->kind() != LIST) { + std::unique_ptr node( + CreateNewNode(string(name), nullptr, LIST, DataPiece::NullData(), false, + child == nullptr ? current_->path() : child->path(), suppress_empty_list_, preserve_proto_field_names_, field_scrub_callback_.get())); child = node.get(); @@ -584,8 +584,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( void DefaultValueObjectWriter::WriteRoot() { root_->WriteTo(ow_); - root_.reset(NULL); - current_ = NULL; + root_.reset(nullptr); + current_ = nullptr; } DefaultValueObjectWriter* DefaultValueObjectWriter::EndList() { @@ -601,7 +601,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::EndList() { void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, const DataPiece& data) { MaybePopulateChildrenOfAny(current_); - if (current_->type() != NULL && current_->type()->name() == kAnyType && + if (current_->type() != nullptr && current_->type()->name() == kAnyType && name == "@type") { util::StatusOr data_string = data.ToString(); if (data_string.ok()) { @@ -621,17 +621,17 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, // other children of primitive type now. Otherwise, we should wait until // the first value field is rendered before we populate the children, // because the "value" field of a Any message could be omitted. - if (current_->number_of_children() > 1 && current_->type() != NULL) { + if (current_->number_of_children() > 1 && current_->type() != nullptr) { current_->PopulateChildren(typeinfo_); } } } Node* child = current_->FindChild(name); - if (child == NULL || child->kind() != PRIMITIVE) { + if (child == nullptr || child->kind() != PRIMITIVE) { // No children are found, creates a new child. - google::protobuf::scoped_ptr node( - CreateNewNode(string(name), NULL, PRIMITIVE, data, false, - child == NULL ? current_->path() : child->path(), + std::unique_ptr node( + CreateNewNode(string(name), nullptr, PRIMITIVE, data, false, + child == nullptr ? current_->path() : child->path(), suppress_empty_list_, preserve_proto_field_names_, field_scrub_callback_.get())); current_->AddChild(node.release()); diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h index 09c6d23f..02cf827a 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.h +++ b/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -32,9 +32,6 @@ #define GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__ #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -77,7 +74,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { FieldScrubCallBack; // A unique pointer to a DefaultValueObjectWriter::FieldScrubCallBack. - typedef google::protobuf::scoped_ptr FieldScrubCallBackPtr; + typedef std::unique_ptr FieldScrubCallBackPtr; DefaultValueObjectWriter(TypeResolver* type_resolver, const google::protobuf::Type& type, @@ -272,7 +269,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { void MaybePopulateChildrenOfAny(Node* node); // Writes the root_ node to ow_ and resets the root_ and current_ pointer to - // NULL. + // nullptr. void WriteRoot(); // Adds or replaces the data_ of a primitive child node. @@ -297,7 +294,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // The current Node. Owned by its parents. Node* current_; // The root Node. - google::protobuf::scoped_ptr root_; + std::unique_ptr root_; // The stack to hold the path of Nodes from current_ to root_; std::stack stack_; diff --git a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc index e1dd697a..0c4af61b 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc @@ -60,7 +60,7 @@ class BaseDefaultValueObjectWriterTest TypeInfoTestHelper helper_; MockObjectWriter mock_; ExpectingObjectWriter expects_; - google::protobuf::scoped_ptr testing_; + std::unique_ptr testing_; }; // Tests to cover some basic DefaultValueObjectWriter use cases. More tests are @@ -156,7 +156,7 @@ class DefaultValueObjectWriterSuppressListTest : BaseDefaultValueObjectWriterTest(DefaultValueTest::descriptor()) { testing_->set_suppress_empty_list(true); } - ~DefaultValueObjectWriterSuppressListTest() {} + ~DefaultValueObjectWriterSuppressListTest() override {} }; INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest, diff --git a/src/google/protobuf/util/internal/error_listener.h b/src/google/protobuf/util/internal/error_listener.h index 1dc814a3..a19bd3f7 100644 --- a/src/google/protobuf/util/internal/error_listener.h +++ b/src/google/protobuf/util/internal/error_listener.h @@ -33,9 +33,6 @@ #include #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc index 38835f67..778a4510 100644 --- a/src/google/protobuf/util/internal/field_mask_utility.cc +++ b/src/google/protobuf/util/internal/field_mask_utility.cc @@ -30,6 +30,7 @@ #include +#include #include #include @@ -53,7 +54,7 @@ string AppendPathSegmentToPrefix(StringPiece prefix, StringPiece segment) { return prefix.ToString(); } // If the segment is a map key, appends it to the prefix without the ".". - if (segment.starts_with("[\"")) { + if (StringStartsWith(segment, "[\"")) { return StrCat(prefix, segment); } return StrCat(prefix, ".", segment); diff --git a/src/google/protobuf/util/internal/json_objectwriter.h b/src/google/protobuf/util/internal/json_objectwriter.h index 81da0500..81644dab 100644 --- a/src/google/protobuf/util/internal/json_objectwriter.h +++ b/src/google/protobuf/util/internal/json_objectwriter.h @@ -32,9 +32,6 @@ #define GOOGLE_PROTOBUF_UTIL_CONVERTER_JSON_OBJECTWRITER_H__ #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -89,7 +86,7 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter { public: JsonObjectWriter(StringPiece indent_string, google::protobuf::io::CodedOutputStream* out) - : element_(new Element(/*parent=*/NULL, /*is_json_object=*/false)), + : element_(new Element(/*parent=*/nullptr, /*is_json_object=*/false)), stream_(out), sink_(out), indent_string_(indent_string.ToString()), @@ -211,7 +208,7 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter { // Writes an individual character to the output. void WriteChar(const char c) { stream_->WriteRaw(&c, sizeof(c)); } - google::protobuf::scoped_ptr element_; + std::unique_ptr element_; google::protobuf::io::CodedOutputStream* stream_; ByteSinkWrapper sink_; const string indent_string_; diff --git a/src/google/protobuf/util/internal/json_objectwriter_test.cc b/src/google/protobuf/util/internal/json_objectwriter_test.cc index 8cc588a6..0dc710c7 100644 --- a/src/google/protobuf/util/internal/json_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/json_objectwriter_test.cc @@ -47,7 +47,7 @@ class JsonObjectWriterTest : public ::testing::Test { JsonObjectWriterTest() : str_stream_(new StringOutputStream(&output_)), out_stream_(new CodedOutputStream(str_stream_)), - ow_(NULL) {} + ow_(nullptr) {} virtual ~JsonObjectWriterTest() { delete ow_; diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc index 2ada3583..1c63b31d 100644 --- a/src/google/protobuf/util/internal/json_stream_parser.cc +++ b/src/google/protobuf/util/internal/json_stream_parser.cc @@ -36,9 +36,6 @@ #include #include #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -157,7 +154,7 @@ util::Status JsonStreamParser::FinishParse() { } // Storage for UTF8-coerced string. - google::protobuf::scoped_array utf8; + std::unique_ptr utf8; if (coerce_to_utf8_) { utf8.reset(new char[leftover_.size()]); char* coerced = internal::UTF8CoerceToStructurallyValid(leftover_, utf8.get(), ' '); diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc index 8bebf2ab..9107e404 100644 --- a/src/google/protobuf/util/internal/proto_writer.cc +++ b/src/google/protobuf/util/internal/proto_writer.cc @@ -66,7 +66,7 @@ ProtoWriter::ProtoWriter(TypeResolver* type_resolver, done_(false), ignore_unknown_fields_(false), use_lower_camel_for_enums_(false), - element_(NULL), + element_(nullptr), size_insert_(), output_(output), buffer_(), @@ -85,7 +85,7 @@ ProtoWriter::ProtoWriter(const TypeInfo* typeinfo, done_(false), ignore_unknown_fields_(false), use_lower_camel_for_enums_(false), - element_(NULL), + element_(nullptr), size_insert_(), output_(output), buffer_(), @@ -99,14 +99,14 @@ ProtoWriter::~ProtoWriter() { if (own_typeinfo_) { delete typeinfo_; } - if (element_ == NULL) return; + if (element_ == nullptr) return; // Cleanup explicitly in order to avoid destructor stack overflow when input // is deeply nested. // Cast to BaseElement to avoid doing additional checks (like missing fields) // during pop(). - google::protobuf::scoped_ptr element( + std::unique_ptr element( static_cast(element_.get())->pop()); - while (element != NULL) { + while (element != nullptr) { element.reset(element->pop()); } } @@ -294,9 +294,9 @@ std::set GetRequiredFields( ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type, ProtoWriter* enclosing) - : BaseElement(NULL), + : BaseElement(nullptr), ow_(enclosing), - parent_field_(NULL), + parent_field_(nullptr), typeinfo_(typeinfo), proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3), type_(type), @@ -374,7 +374,7 @@ ProtoWriter::ProtoElement* ProtoWriter::ProtoElement::pop() { // all enclosing messages. int size = ow_->size_insert_[size_index_].size; int length = CodedOutputStream::VarintSize32(size); - for (ProtoElement* e = parent(); e != NULL; e = e->parent()) { + for (ProtoElement* e = parent(); e != nullptr; e = e->parent()) { // Only nested messages have size field, lists do not have size field. if (e->size_index_ >= 0) { ow_->size_insert_[e->size_index_].size += length; @@ -394,7 +394,7 @@ void ProtoWriter::ProtoElement::RegisterField( } string ProtoWriter::ProtoElement::ToString() const { - if (parent() == NULL) return ""; + if (parent() == nullptr) return ""; string loc = parent()->ToString(); if (!ow_->IsRepeated(*parent_field_) || parent()->parent_field_ != parent_field_) { @@ -439,7 +439,7 @@ void ProtoWriter::MissingField(StringPiece missing_name) { ProtoWriter* ProtoWriter::StartObject(StringPiece name) { // Starting the root message. Create the root ProtoElement and return. - if (element_ == NULL) { + if (element_ == nullptr) { if (!name.empty()) { InvalidName(name, "Root element should not be named."); } @@ -447,9 +447,9 @@ ProtoWriter* ProtoWriter::StartObject(StringPiece name) { return this; } - const google::protobuf::Field* field = NULL; + const google::protobuf::Field* field = nullptr; field = BeginNamed(name, false); - if (field == NULL) return this; + if (field == nullptr) return this; // Check to see if this field is a oneof and that no oneof in that group has // already been set. @@ -459,7 +459,7 @@ ProtoWriter* ProtoWriter::StartObject(StringPiece name) { } const google::protobuf::Type* type = LookupType(field); - if (type == NULL) { + if (type == nullptr) { ++invalid_depth_; InvalidName(name, StrCat("Missing descriptor for field: ", field->type_url())); @@ -475,14 +475,14 @@ ProtoWriter* ProtoWriter::EndObject() { return this; } - if (element_ != NULL) { + if (element_ != nullptr) { element_.reset(element_->pop()); } // If ending the root element, // then serialize the full message with calculated sizes. - if (element_ == NULL) { + if (element_ == nullptr) { WriteRootMessage(); } return this; @@ -490,7 +490,7 @@ ProtoWriter* ProtoWriter::EndObject() { ProtoWriter* ProtoWriter::StartList(StringPiece name) { const google::protobuf::Field* field = BeginNamed(name, true); - if (field == NULL) return this; + if (field == nullptr) return this; if (!ValidOneof(*field, name)) { ++invalid_depth_; @@ -498,7 +498,7 @@ ProtoWriter* ProtoWriter::StartList(StringPiece name) { } const google::protobuf::Type* type = LookupType(field); - if (type == NULL) { + if (type == nullptr) { ++invalid_depth_; InvalidName(name, StrCat("Missing descriptor for field: ", field->type_url())); @@ -511,7 +511,7 @@ ProtoWriter* ProtoWriter::StartList(StringPiece name) { ProtoWriter* ProtoWriter::EndList() { if (invalid_depth_ > 0) { --invalid_depth_; - } else if (element_ != NULL) { + } else if (element_ != nullptr) { element_.reset(element_->pop()); } return this; @@ -523,12 +523,12 @@ ProtoWriter* ProtoWriter::RenderDataPiece(StringPiece name, if (invalid_depth_ > 0) return this; const google::protobuf::Field* field = Lookup(name); - if (field == NULL) return this; + if (field == nullptr) return this; if (!ValidOneof(*field, name)) return this; const google::protobuf::Type* type = LookupType(field); - if (type == NULL) { + if (type == nullptr) { InvalidName(name, StrCat("Missing descriptor for field: ", field->type_url())); return this; @@ -539,7 +539,7 @@ ProtoWriter* ProtoWriter::RenderDataPiece(StringPiece name, bool ProtoWriter::ValidOneof(const google::protobuf::Field& field, StringPiece unnormalized_name) { - if (element_ == NULL) return true; + if (element_ == nullptr) return true; if (field.oneof_index() > 0) { if (element_->IsOneofIndexTaken(field.oneof_index())) { @@ -692,18 +692,18 @@ const google::protobuf::Field* ProtoWriter::BeginNamed(StringPiece name, bool is_list) { if (invalid_depth_ > 0) { ++invalid_depth_; - return NULL; + return nullptr; } const google::protobuf::Field* field = Lookup(name); - if (field == NULL) { + if (field == nullptr) { ++invalid_depth_; // InvalidName() already called in Lookup(). - return NULL; + return nullptr; } if (is_list && !IsRepeated(*field)) { ++invalid_depth_; InvalidName(name, "Proto field is not repeating, cannot start list."); - return NULL; + return nullptr; } return field; } @@ -711,23 +711,23 @@ const google::protobuf::Field* ProtoWriter::BeginNamed(StringPiece name, const google::protobuf::Field* ProtoWriter::Lookup( StringPiece unnormalized_name) { ProtoElement* e = element(); - if (e == NULL) { + if (e == nullptr) { InvalidName(unnormalized_name, "Root element must be a message."); - return NULL; + return nullptr; } if (unnormalized_name.empty()) { // Objects in repeated field inherit the same field descriptor. - if (e->parent_field() == NULL) { + if (e->parent_field() == nullptr) { InvalidName(unnormalized_name, "Proto fields must have a name."); } else if (!IsRepeated(*e->parent_field())) { InvalidName(unnormalized_name, "Proto fields must have a name."); - return NULL; + return nullptr; } return e->parent_field(); } const google::protobuf::Field* field = typeinfo_->FindField(&e->type(), unnormalized_name); - if (field == NULL && !ignore_unknown_fields_) { + if (field == nullptr && !ignore_unknown_fields_) { InvalidName(unnormalized_name, "Cannot find field."); } return field; @@ -746,7 +746,7 @@ void ProtoWriter::WriteRootMessage() { int curr_pos = 0; // Calls the destructor of CodedOutputStream to remove any uninitialized // memory from the Cord before we read it. - stream_.reset(NULL); + stream_.reset(nullptr); const void* data; int length; google::protobuf::io::ArrayInputStream input_stream(buffer_.data(), buffer_.size()); diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h index 0db8485c..89ca0e86 100644 --- a/src/google/protobuf/util/internal/proto_writer.h +++ b/src/google/protobuf/util/internal/proto_writer.h @@ -81,32 +81,32 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { virtual ~ProtoWriter(); // ObjectWriter methods. - ProtoWriter* StartObject(StringPiece name); - ProtoWriter* EndObject(); - ProtoWriter* StartList(StringPiece name); - ProtoWriter* EndList(); - ProtoWriter* RenderBool(StringPiece name, bool value) { + ProtoWriter* StartObject(StringPiece name) override; + ProtoWriter* EndObject() override; + ProtoWriter* StartList(StringPiece name) override; + ProtoWriter* EndList() override; + ProtoWriter* RenderBool(StringPiece name, bool value) override { return RenderDataPiece(name, DataPiece(value)); } - ProtoWriter* RenderInt32(StringPiece name, int32 value) { + ProtoWriter* RenderInt32(StringPiece name, int32 value) override { return RenderDataPiece(name, DataPiece(value)); } - ProtoWriter* RenderUint32(StringPiece name, uint32 value) { + ProtoWriter* RenderUint32(StringPiece name, uint32 value) override { return RenderDataPiece(name, DataPiece(value)); } - ProtoWriter* RenderInt64(StringPiece name, int64 value) { + ProtoWriter* RenderInt64(StringPiece name, int64 value) override { return RenderDataPiece(name, DataPiece(value)); } - ProtoWriter* RenderUint64(StringPiece name, uint64 value) { + ProtoWriter* RenderUint64(StringPiece name, uint64 value) override { return RenderDataPiece(name, DataPiece(value)); } - ProtoWriter* RenderDouble(StringPiece name, double value) { + ProtoWriter* RenderDouble(StringPiece name, double value) override { return RenderDataPiece(name, DataPiece(value)); } - ProtoWriter* RenderFloat(StringPiece name, float value) { + ProtoWriter* RenderFloat(StringPiece name, float value) override { return RenderDataPiece(name, DataPiece(value)); } - ProtoWriter* RenderString(StringPiece name, StringPiece value) { + ProtoWriter* RenderString(StringPiece name, StringPiece value) override { return RenderDataPiece(name, DataPiece(value, use_strict_base64_decoding())); } @@ -114,7 +114,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { return RenderDataPiece( name, DataPiece(value, false, use_strict_base64_decoding())); } - ProtoWriter* RenderNull(StringPiece name) { + ProtoWriter* RenderNull(StringPiece name) override { return RenderDataPiece(name, DataPiece::NullData()); } @@ -126,11 +126,11 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // Returns the location tracker to use for tracking locations for errors. const LocationTrackerInterface& location() { - return element_ != NULL ? *element_ : *tracker_; + return element_ != nullptr ? *element_ : *tracker_; } // When true, we finished writing to output a complete message. - bool done() { return done_; } + bool done() override { return done_; } // Returns the proto stream object. google::protobuf::io::CodedOutputStream* stream() { return stream_.get(); } @@ -173,7 +173,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { ProtoElement* pop(); // Accessors - // parent_field() may be NULL if we are at root. + // parent_field() may be nullptr if we are at root. const google::protobuf::Field* parent_field() const { return parent_field_; } @@ -204,7 +204,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { ProtoWriter* ow_; // Describes the element as a field in the parent message. - // parent_field_ is NULL if and only if this element is the root element. + // parent_field_ is nullptr if and only if this element is the root element. const google::protobuf::Field* parent_field_; // TypeInfo to lookup types. @@ -242,7 +242,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type, strings::ByteSink* output, ErrorListener* listener); - ProtoElement* element() { return element_.get(); } + ProtoElement* element() override { return element_.get(); } // Helper methods for calling ErrorListener. See error_listener.h. void InvalidName(StringPiece unknown_name, StringPiece message); @@ -259,7 +259,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // extensions are found. const google::protobuf::Field* Lookup(StringPiece name); - // Lookup the field type in the type descriptor. Returns NULL if the type + // Lookup the field type in the type descriptor. Returns nullptr if the type // is not known. const google::protobuf::Type* LookupType( const google::protobuf::Field* field); @@ -321,7 +321,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // size_insert_: sizes of nested messages. // pos - position to insert the size field. // size - size value to be inserted. - google::protobuf::scoped_ptr element_; + std::unique_ptr element_; std::deque size_insert_; // Variables for output generation: @@ -332,7 +332,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { strings::ByteSink* output_; string buffer_; google::protobuf::io::StringOutputStream adapter_; - google::protobuf::scoped_ptr stream_; + std::unique_ptr stream_; // Variables for error tracking and reporting: // listener_ : a place to report any errors found. @@ -340,7 +340,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { // tracker_ : the root location tracker interface. ErrorListener* listener_; int invalid_depth_; - google::protobuf::scoped_ptr tracker_; + std::unique_ptr tracker_; GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoWriter); }; diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 72ad5a7a..56e6db12 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -73,14 +73,14 @@ namespace { static int kDefaultMaxRecursionDepth = 64; -// Finds a field with the given number. NULL if none found. +// Finds a field with the given number. nullptr if none found. const google::protobuf::Field* FindFieldByNumber( const google::protobuf::Type& type, int number); // Returns true if the field is packable. bool IsPackable(const google::protobuf::Field& field); -// Finds an enum value with the given number. NULL if none found. +// Finds an enum value with the given number. nullptr if none found. const google::protobuf::EnumValue* FindEnumValueByNumber( const google::protobuf::Enum& tech_enum, int number); @@ -127,7 +127,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( render_unknown_fields_(false), render_unknown_enum_values_(true), add_trailing_zeros_for_timestamp_and_duration_(false) { - GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL."; + GOOGLE_LOG_IF(DFATAL, stream == nullptr) << "Input stream is nullptr."; } ProtoStreamObjectSource::ProtoStreamObjectSource( @@ -145,7 +145,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource( render_unknown_fields_(false), render_unknown_enum_values_(true), add_trailing_zeros_for_timestamp_and_duration_(false) { - GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL."; + GOOGLE_LOG_IF(DFATAL, stream == nullptr) << "Input stream is nullptr."; } ProtoStreamObjectSource::~ProtoStreamObjectSource() { @@ -165,7 +165,7 @@ const google::protobuf::Field* ProtoStreamObjectSource::FindAndVerifyField( const google::protobuf::Field* field = FindFieldByNumber(type, tag >> 3); // Verify if the field corresponds to the wire type in tag. // If there is any discrepancy, mark the field as not found. - if (field != NULL) { + if (field != nullptr) { WireFormatLite::WireType expected_type = WireFormatLite::WireTypeForFieldType( static_cast(field->kind())); @@ -173,7 +173,7 @@ const google::protobuf::Field* ProtoStreamObjectSource::FindAndVerifyField( if (actual_type != expected_type && (!IsPackable(*field) || actual_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED)) { - field = NULL; + field = nullptr; } } return field; @@ -186,11 +186,11 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, ObjectWriter* ow) const { const TypeRenderer* type_renderer = FindTypeRenderer(type.name()); - if (type_renderer != NULL) { + if (type_renderer != nullptr) { return (*type_renderer)(this, type, name, ow); } - const google::protobuf::Field* field = NULL; + const google::protobuf::Field* field = nullptr; string field_name; // last_tag set to dummy value that is different from tag. uint32 tag = stream_->ReadTag(), last_tag = tag + 1; @@ -203,7 +203,7 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, if (tag != last_tag) { // Update field only if tag is changed. last_tag = tag; field = FindAndVerifyField(type, tag); - if (field != NULL) { + if (field != nullptr) { if (preserve_proto_field_names_) { field_name = field->name(); } else { @@ -211,11 +211,11 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, } } } - if (field == NULL) { + if (field == nullptr) { // If we didn't find a field, skip this unknown tag. // TODO(wpoon): Check return boolean value. WireFormat::SkipField(stream_, tag, - render_unknown_fields_ ? &unknown_fields : NULL); + render_unknown_fields_ ? &unknown_fields : nullptr); tag = stream_->ReadTag(); continue; } @@ -282,8 +282,8 @@ StatusOr ProtoStreamObjectSource::RenderMap( for (uint32 tag = stream_->ReadTag(); tag != 0; tag = stream_->ReadTag()) { const google::protobuf::Field* field = FindAndVerifyField(*field_type, tag); - if (field == NULL) { - WireFormat::SkipField(stream_, tag, NULL); + if (field == nullptr) { + WireFormat::SkipField(stream_, tag, nullptr); continue; } // Map field numbers are key = 1 and value = 2 @@ -294,7 +294,7 @@ StatusOr ProtoStreamObjectSource::RenderMap( // An absent map key is treated as the default. const google::protobuf::Field* key_field = FindFieldByNumber(*field_type, 1); - if (key_field == NULL) { + 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."); @@ -525,7 +525,7 @@ Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { - const google::protobuf::Field* field = NULL; + const google::protobuf::Field* field = nullptr; uint32 tag = os->stream_->ReadTag(); ow->StartObject(field_name); while (tag != 0) { @@ -543,12 +543,12 @@ Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, Status ProtoStreamObjectSource::RenderStructValue( const ProtoStreamObjectSource* os, const google::protobuf::Type& type, StringPiece field_name, ObjectWriter* ow) { - const google::protobuf::Field* field = NULL; + const google::protobuf::Field* field = nullptr; for (uint32 tag = os->stream_->ReadTag(); tag != 0; tag = os->stream_->ReadTag()) { field = os->FindAndVerifyField(type, tag); - if (field == NULL) { - WireFormat::SkipField(os->stream_, tag, NULL); + if (field == nullptr) { + WireFormat::SkipField(os->stream_, tag, nullptr); continue; } RETURN_IF_ERROR(os->RenderField(field, field_name, ow)); @@ -571,8 +571,8 @@ Status ProtoStreamObjectSource::RenderStructListValue( while (tag != 0) { const google::protobuf::Field* field = os->FindAndVerifyField(type, tag); - if (field == NULL) { - WireFormat::SkipField(os->stream_, tag, NULL); + if (field == nullptr) { + WireFormat::SkipField(os->stream_, tag, nullptr); tag = os->stream_->ReadTag(); continue; } @@ -593,8 +593,8 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, // First read out the type_url and value from the proto stream for (tag = os->stream_->ReadTag(); tag != 0; tag = os->stream_->ReadTag()) { const google::protobuf::Field* field = os->FindAndVerifyField(type, tag); - if (field == NULL) { - WireFormat::SkipField(os->stream_, tag, NULL); + if (field == nullptr) { + WireFormat::SkipField(os->stream_, tag, nullptr); continue; } // 'type_url' has field number of 1 and 'value' has field number 2 @@ -667,7 +667,7 @@ Status ProtoStreamObjectSource::RenderFieldMask( tag = os->stream_->ReadTag()) { if (paths_field_tag == 0) { const google::protobuf::Field* field = os->FindAndVerifyField(type, tag); - if (field != NULL && field->number() == 1 && + if (field != nullptr && field->number() == 1 && field->name() == "paths") { paths_field_tag = tag; } @@ -754,7 +754,7 @@ Status ProtoStreamObjectSource::RenderField( // Get the nested message type for this field. const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(field->type_url()); - if (type == NULL) { + if (type == nullptr) { return Status(util::error::INTERNAL, StrCat("Invalid configuration. Could not find the type: ", field->type_url())); @@ -763,7 +763,7 @@ Status ProtoStreamObjectSource::RenderField( // Short-circuit any special type rendering to save call-stack space. const TypeRenderer* type_renderer = FindTypeRenderer(type->name()); - bool use_type_renderer = type_renderer != NULL; + bool use_type_renderer = type_renderer != nullptr; if (use_type_renderer) { RETURN_IF_ERROR((*type_renderer)(this, *type, field_name, ow)); @@ -873,14 +873,15 @@ Status ProtoStreamObjectSource::RenderNonMessageField( typeinfo_->GetEnumByTypeUrl(field->type_url()); // Lookup the name of the enum, and render that. Unknown enum values // are printed as integers. - if (en != NULL) { + if (en != nullptr) { const google::protobuf::EnumValue* enum_value = FindEnumValueByNumber(*en, buffer32); - if (enum_value != NULL) { + if (enum_value != nullptr) { if (use_ints_for_enums_) { ow->RenderInt32(field_name, buffer32); } else if (use_lower_camel_for_enums_) { - ow->RenderString(field_name, ToCamelCase(enum_value->name())); + ow->RenderString(field_name, + EnumValueNameToLowerCamelCase(enum_value->name())); } else { ow->RenderString(field_name, enum_value->name()); } @@ -1002,10 +1003,10 @@ const string ProtoStreamObjectSource::ReadFieldValueAsString( const google::protobuf::Enum* en = typeinfo_->GetEnumByTypeUrl(field.type_url()); // Lookup the name of the enum, and render that. Skips unknown enums. - if (en != NULL) { + if (en != nullptr) { const google::protobuf::EnumValue* enum_value = FindEnumValueByNumber(*en, buffer32); - if (enum_value != NULL) { + if (enum_value != nullptr) { result = enum_value->name(); } } @@ -1049,8 +1050,8 @@ std::pair ProtoStreamObjectSource::ReadSecondsAndNanos( for (tag = stream_->ReadTag(); tag != 0; tag = stream_->ReadTag()) { const google::protobuf::Field* field = FindAndVerifyField(type, tag); - if (field == NULL) { - WireFormat::SkipField(stream_, tag, NULL); + if (field == nullptr) { + WireFormat::SkipField(stream_, tag, nullptr); continue; } // 'seconds' has field number of 1 and 'nanos' has field number 2 @@ -1088,7 +1089,7 @@ const google::protobuf::Field* FindFieldByNumber( return &type.fields(i); } } - return NULL; + return nullptr; } // TODO(skarvaje): Replace FieldDescriptor by implementing IsTypePackable() @@ -1109,7 +1110,7 @@ const google::protobuf::EnumValue* FindEnumValueByNumber( return &ev; } } - return NULL; + return nullptr; } // TODO(skarvaje): Look into optimizing this by not doing computation on diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc index 36bb1ba9..df790728 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc @@ -31,9 +31,6 @@ #include #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -122,7 +119,7 @@ class ProtostreamObjectSourceTest ArrayInputStream arr_stream(proto.data(), proto.size()); CodedInputStream in_stream(&arr_stream); - google::protobuf::scoped_ptr os( + std::unique_ptr os( helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor))); if (use_lower_camel_for_enums_) os->set_use_lower_camel_for_enums(true); if (use_ints_for_enums_) os->set_use_ints_for_enums(true); @@ -490,7 +487,7 @@ TEST_P(ProtostreamObjectSourceTest, DoTest(book, Book::descriptor()); } -TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputTest) { +TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputMacroCase) { Book book; book.set_type(Book::ACTION_AND_ADVENTURE); @@ -500,6 +497,26 @@ TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputTest) { DoTest(book, Book::descriptor()); } +TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputSnakeCase) { + Book book; + book.set_type(Book::arts_and_photography); + + UseLowerCamelForEnums(); + + ow_.StartObject("")->RenderString("type", "artsAndPhotography")->EndObject(); + DoTest(book, Book::descriptor()); +} + +TEST_P(ProtostreamObjectSourceTest, LowerCamelEnumOutputWithNumber) { + Book book; + book.set_type(Book::I18N_Tech); + + UseLowerCamelForEnums(); + + ow_.StartObject("")->RenderString("type", "i18nTech")->EndObject(); + DoTest(book, Book::descriptor()); +} + TEST_P(ProtostreamObjectSourceTest, EnumCaseIsUnchangedByDefault) { Book book; book.set_type(Book::ACTION_AND_ADVENTURE); diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 97f96819..2edfd075 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -62,7 +62,7 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter( const ProtoStreamObjectWriter::Options& options) : ProtoWriter(type_resolver, type, output, listener), master_type_(type), - current_(NULL), + current_(nullptr), options_(options) { set_ignore_unknown_fields(options_.ignore_unknown_fields); set_use_lower_camel_for_enums(options_.use_lower_camel_for_enums); @@ -73,18 +73,18 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter( strings::ByteSink* output, ErrorListener* listener) : ProtoWriter(typeinfo, type, output, listener), master_type_(type), - current_(NULL), + current_(nullptr), options_(ProtoStreamObjectWriter::Options::Defaults()) {} ProtoStreamObjectWriter::~ProtoStreamObjectWriter() { - if (current_ == NULL) return; + if (current_ == nullptr) return; // Cleanup explicitly in order to avoid destructor stack overflow when input // is deeply nested. // Cast to BaseElement to avoid doing additional checks (like missing fields) // during pop(). - google::protobuf::scoped_ptr element( + std::unique_ptr element( static_cast(current_.get())->pop()); - while (element != NULL) { + while (element != nullptr) { element.reset(element->pop()); } } @@ -186,7 +186,7 @@ ProtoStreamObjectWriter::AnyWriter::AnyWriter(ProtoStreamObjectWriter* parent) output_(&data_), depth_(0), is_well_known_type_(false), - well_known_type_render_(NULL) {} + well_known_type_render_(nullptr) {} ProtoStreamObjectWriter::AnyWriter::~AnyWriter() {} @@ -195,7 +195,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartObject(StringPiece name) { // If an object writer is absent, that means we have not called StartAny() // before reaching here, which happens when we have data before the "@type" // field. - if (ow_ == NULL) { + if (ow_ == nullptr) { // Save data before the "@type" field for later replay. uninterpreted_events_.push_back(Event(Event::START_OBJECT, name)); } else if (is_well_known_type_ && depth_ == 1) { @@ -217,7 +217,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartObject(StringPiece name) { bool ProtoStreamObjectWriter::AnyWriter::EndObject() { --depth_; - if (ow_ == NULL) { + if (ow_ == nullptr) { if (depth_ >= 0) { // Save data before the "@type" field for later replay. uninterpreted_events_.push_back(Event(Event::END_OBJECT)); @@ -239,7 +239,7 @@ bool ProtoStreamObjectWriter::AnyWriter::EndObject() { void ProtoStreamObjectWriter::AnyWriter::StartList(StringPiece name) { ++depth_; - if (ow_ == NULL) { + if (ow_ == nullptr) { // Save data before the "@type" field for later replay. uninterpreted_events_.push_back(Event(Event::START_LIST, name)); } else if (is_well_known_type_ && depth_ == 1) { @@ -260,7 +260,7 @@ void ProtoStreamObjectWriter::AnyWriter::EndList() { GOOGLE_LOG(DFATAL) << "Mismatched EndList found, should not be possible"; depth_ = 0; } - if (ow_ == NULL) { + if (ow_ == nullptr) { // Save data before the "@type" field for later replay. uninterpreted_events_.push_back(Event(Event::END_LIST)); } else { @@ -272,9 +272,9 @@ void ProtoStreamObjectWriter::AnyWriter::RenderDataPiece( StringPiece name, const DataPiece& value) { // Start an Any only at depth_ 0. Other RenderDataPiece calls with "@type" // should go to the contained ow_ as they indicate nested Anys. - if (depth_ == 0 && ow_ == NULL && name == "@type") { + if (depth_ == 0 && ow_ == nullptr && name == "@type") { StartAny(value); - } else if (ow_ == NULL) { + } else if (ow_ == nullptr) { // Save data before the "@type" field. uninterpreted_events_.push_back(Event(name, value)); } else if (depth_ == 0 && is_well_known_type_) { @@ -283,7 +283,7 @@ void ProtoStreamObjectWriter::AnyWriter::RenderDataPiece( "Expect a \"value\" field for well-known types."); invalid_ = true; } - if (well_known_type_render_ == NULL) { + if (well_known_type_render_ == nullptr) { // Only Any and Struct don't have a special type render but both of // them expect a JSON object (i.e., a StartObject() call). if (value.type() != DataPiece::TYPE_NULL && !invalid_) { @@ -327,7 +327,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { const google::protobuf::Type* type = resolved_type.ValueOrDie(); well_known_type_render_ = FindTypeRenderer(type_url_); - if (well_known_type_render_ != NULL || + if (well_known_type_render_ != nullptr || // Explicitly list Any and Struct here because they don't have a // custom renderer. type->name() == kAnyType || type->name() == kStructType) { @@ -360,7 +360,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) { } void ProtoStreamObjectWriter::AnyWriter::WriteAny() { - if (ow_ == NULL) { + if (ow_ == nullptr) { if (uninterpreted_events_.empty()) { // We never got any content, so just return immediately, which is // equivalent to writing an empty Any. @@ -421,7 +421,7 @@ void ProtoStreamObjectWriter::AnyWriter::Event::DeepCopy() { ProtoStreamObjectWriter::Item::Item(ProtoStreamObjectWriter* enclosing, ItemType item_type, bool is_placeholder, bool is_list) - : BaseElement(NULL), + : BaseElement(nullptr), ow_(enclosing), any_(), item_type_(item_type), @@ -467,7 +467,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( // Starting the root message. Create the root Item and return. // ANY message type does not need special handling, just set the ItemType // to ANY. - if (current_ == NULL) { + if (current_ == nullptr) { ProtoWriter::StartObject(name); current_.reset(new Item( this, master_type_.name() == kAnyType ? Item::ANY : Item::MESSAGE, @@ -541,14 +541,14 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( // If top of stack is g.p.Struct type, start the struct the map field within // it. - if (element() != NULL && IsStruct(*element()->parent_field())) { + if (element() != nullptr && IsStruct(*element()->parent_field())) { // Render "fields": [ Push("fields", Item::MAP, true, true); return this; } // If top of stack is g.p.Value type, start the Struct within it. - if (element() != NULL && IsStructValue(*element()->parent_field())) { + if (element() != nullptr && IsStructValue(*element()->parent_field())) { // Render // "struct_value": { // "fields": [ @@ -559,7 +559,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject( } const google::protobuf::Field* field = BeginNamed(name, false); - if (field == NULL) return this; + if (field == nullptr) return this; if (IsStruct(*field)) { // Start a struct object. @@ -607,7 +607,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndObject() { return this; } - if (current_ == NULL) return this; + if (current_ == nullptr) return this; if (current_->IsAny()) { if (current_->any()->EndObject()) return this; @@ -627,7 +627,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(StringPiece name) { // Since we cannot have a top-level repeated item in protobuf, the only way // this is valid is if we start a special type google.protobuf.ListValue or // google.protobuf.Value. - if (current_ == NULL) { + if (current_ == nullptr) { if (!name.empty()) { InvalidName(name, "Root element should not be named."); IncrementInvalidDepth(); @@ -706,7 +706,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(StringPiece name) { if (invalid_depth() > 0) return this; // case i and ii above. Start "list_value" field within g.p.Value - if (element() != NULL && element()->parent_field() != NULL) { + if (element() != nullptr && element()->parent_field() != nullptr) { // Render // "list_value": { // "values": [ // Start this list @@ -734,7 +734,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(StringPiece name) { // When name is empty and stack is not empty, we are rendering an item within // a list. if (name.empty()) { - if (element() != NULL && element()->parent_field() != NULL) { + if (element() != nullptr && element()->parent_field() != nullptr) { if (IsStructValue(*element()->parent_field())) { // Since it is g.p.Value, we bind directly to the list_value. // Render @@ -765,7 +765,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(StringPiece name) { // name is not empty const google::protobuf::Field* field = Lookup(name); - if (field == NULL) { + if (field == nullptr) { IncrementInvalidDepth(); return this; } @@ -837,7 +837,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::EndList() { return this; } - if (current_ == NULL) return this; + if (current_ == nullptr) return this; if (current_->IsAny()) { current_->any()->EndList(); @@ -961,7 +961,7 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow, // TODO(tsun): figure out how to do proto descriptor based snake case // conversions as much as possible. Because ToSnakeCase sometimes returns the // wrong value. - google::protobuf::scoped_ptr > callback( + std::unique_ptr > callback( ::google::protobuf::NewPermanentCallback(&RenderOneFieldPath, ow)); return DecodeCompactFieldMaskPaths(data.str(), callback.get()); } @@ -977,13 +977,13 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow, StringPiece value(data.str()); - if (!value.ends_with("s")) { + if (!StringEndsWith(value, "s")) { return Status(INVALID_ARGUMENT, "Illegal duration format; duration must end with 's'"); } value = value.substr(0, value.size() - 1); int sign = 1; - if (value.starts_with("-")) { + if (StringStartsWith(value, "-")) { sign = -1; value = value.substr(1); } @@ -1028,10 +1028,10 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( Status status; if (invalid_depth() > 0) return this; - if (current_ == NULL) { + if (current_ == nullptr) { const TypeRenderer* type_renderer = FindTypeRenderer(GetFullTypeWithUrl(master_type_.name())); - if (type_renderer == NULL) { + if (type_renderer == nullptr) { InvalidName(name, "Root element must be a message."); return this; } @@ -1054,7 +1054,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( return this; } - const google::protobuf::Field* field = NULL; + const google::protobuf::Field* field = nullptr; if (current_->IsMap()) { if (!ValidMapKey(name)) return this; @@ -1064,14 +1064,14 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( ProtoWriter::RenderDataPiece("key", DataPiece(name, use_strict_base64_decoding())); field = Lookup("value"); - if (field == NULL) { + if (field == nullptr) { Pop(); GOOGLE_LOG(DFATAL) << "Map does not have a value field."; return this; } const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url()); - if (type_renderer != NULL) { + if (type_renderer != nullptr) { // Map's value type is a special type. Render it like a message: // "value": { // ... Render special type ... @@ -1101,11 +1101,11 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( } field = Lookup(name); - if (field == NULL) return this; + if (field == nullptr) return this; // Check if the field is of special type. Render it accordingly if so. const TypeRenderer* type_renderer = FindTypeRenderer(field->type_url()); - if (type_renderer != NULL) { + if (type_renderer != nullptr) { // Pass through null value only for google.protobuf.Value. For other // types we ignore null value just like for regular field types. if (data.type() != DataPiece::TYPE_NULL || @@ -1199,7 +1199,7 @@ ProtoStreamObjectWriter::FindTypeRenderer(const string& type_url) { } bool ProtoStreamObjectWriter::ValidMapKey(StringPiece unnormalized_name) { - if (current_ == NULL) return true; + if (current_ == nullptr) return true; if (!current_->InsertMapKeyIfNotPresent(unnormalized_name)) { listener()->InvalidName( @@ -1224,10 +1224,10 @@ void ProtoStreamObjectWriter::Push(StringPiece name, Item::ItemType item_type, void ProtoStreamObjectWriter::Pop() { // Pop all placeholder items sending StartObject or StartList events to // ProtoWriter according to is_list value. - while (current_ != NULL && current_->is_placeholder()) { + while (current_ != nullptr && current_->is_placeholder()) { PopOneElement(); } - if (current_ != NULL) { + if (current_ != nullptr) { PopOneElement(); } } diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h index ab534912..c33a4639 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.h +++ b/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -216,7 +216,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { ProtoStreamObjectWriter* parent_; // The nested object writer, used to write events. - google::protobuf::scoped_ptr ow_; + std::unique_ptr ow_; // The type_url_ that this Any represents. string type_url_; @@ -292,14 +292,14 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { ProtoStreamObjectWriter* ow_; // A writer for Any objects, handles all Any-related nonsense. - google::protobuf::scoped_ptr any_; + std::unique_ptr any_; // The type of this element, see enum for permissible types. ItemType item_type_; // Set of map keys already seen for the type_. Used to validate incoming // messages so no map key appears more than once. - google::protobuf::scoped_ptr > map_keys_; + std::unique_ptr > map_keys_; // Conveys whether this Item is a placeholder or not. Placeholder items are // pushed to stack to account for special types. @@ -392,7 +392,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { const google::protobuf::Type& master_type_; // The current element, variable for internal state processing. - google::protobuf::scoped_ptr current_; + std::unique_ptr current_; // Reference to the options that control this class's behavior. const ProtoStreamObjectWriter::Options options_; diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index 87d35b08..7f0df567 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -146,7 +146,7 @@ class BaseProtoStreamObjectWriterTest void CheckOutput(const Message& expected, int expected_length) { size_t nbytes; - google::protobuf::scoped_array buffer(output_->GetBuffer(&nbytes)); + std::unique_ptr buffer(output_->GetBuffer(&nbytes)); if (expected_length >= 0) { EXPECT_EQ(expected_length, nbytes); } @@ -154,7 +154,7 @@ class BaseProtoStreamObjectWriterTest std::stringbuf str_buf(str, std::ios_base::in); std::istream istream(&str_buf); - google::protobuf::scoped_ptr message(expected.New()); + std::unique_ptr message(expected.New()); message->ParsePartialFromIstream(&istream); if (!MessageDifferencer::Equivalent(expected, *message)) { @@ -170,8 +170,8 @@ class BaseProtoStreamObjectWriterTest testing::TypeInfoTestHelper helper_; MockErrorListener listener_; - google::protobuf::scoped_ptr output_; - google::protobuf::scoped_ptr ow_; + std::unique_ptr output_; + std::unique_ptr ow_; ProtoStreamObjectWriter::Options options_; }; diff --git a/src/google/protobuf/util/internal/structured_objectwriter.h b/src/google/protobuf/util/internal/structured_objectwriter.h index 3f065d6b..8e63222b 100644 --- a/src/google/protobuf/util/internal/structured_objectwriter.h +++ b/src/google/protobuf/util/internal/structured_objectwriter.h @@ -32,9 +32,6 @@ #define GOOGLE_PROTOBUF_UTIL_CONVERTER_STRUCTURED_OBJECTWRITER_H__ #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -80,7 +77,7 @@ class LIBPROTOBUF_EXPORT StructuredObjectWriter : public ObjectWriter { } // Returns true if this element is the root. - bool is_root() const { return parent_ == NULL; } + bool is_root() const { return parent_ == nullptr; } // Returns the number of hops from this element to the root element. int level() const { return level_; } @@ -91,10 +88,10 @@ class LIBPROTOBUF_EXPORT StructuredObjectWriter : public ObjectWriter { private: // Pointer to the parent Element. - google::protobuf::scoped_ptr parent_; + std::unique_ptr parent_; // Number of hops to the root Element. - // The root Element has NULL parent_ and a level_ of 0. + // The root Element has nullptr parent_ and a level_ of 0. const int level_; GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(BaseElement); diff --git a/src/google/protobuf/util/internal/testdata/books.proto b/src/google/protobuf/util/internal/testdata/books.proto index 869271f4..5630cc78 100644 --- a/src/google/protobuf/util/internal/testdata/books.proto +++ b/src/google/protobuf/util/internal/testdata/books.proto @@ -65,6 +65,7 @@ message Book { KIDS = 2; ACTION_AND_ADVENTURE = 3; arts_and_photography = 4; + I18N_Tech = 5; } optional Type type = 11; diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index 85d0d5c9..3847b179 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -69,7 +69,7 @@ class TypeInfoForTypeResolver : public TypeInfo { // cached_types_ map. const string& string_type_url = *string_storage_.insert(type_url.ToString()).first; - google::protobuf::scoped_ptr type(new google::protobuf::Type()); + std::unique_ptr type(new google::protobuf::Type()); util::Status status = type_resolver_->ResolveMessageType(string_type_url, type.get()); StatusOrType result = @@ -95,7 +95,7 @@ class TypeInfoForTypeResolver : public TypeInfo { // cached_enums_ map. const string& string_type_url = *string_storage_.insert(type_url.ToString()).first; - google::protobuf::scoped_ptr enum_type( + std::unique_ptr enum_type( new google::protobuf::Enum()); util::Status status = type_resolver_->ResolveEnumType(string_type_url, enum_type.get()); 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 737ba9e4..281a7f58 100644 --- a/src/google/protobuf/util/internal/type_info_test_helper.cc +++ b/src/google/protobuf/util/internal/type_info_test_helper.cc @@ -31,9 +31,6 @@ #include #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include diff --git a/src/google/protobuf/util/internal/type_info_test_helper.h b/src/google/protobuf/util/internal/type_info_test_helper.h index 1a196715..5a077e04 100644 --- a/src/google/protobuf/util/internal/type_info_test_helper.h +++ b/src/google/protobuf/util/internal/type_info_test_helper.h @@ -32,9 +32,6 @@ #define GOOGLE_PROTOBUF_UTIL_CONVERTER_TYPE_INFO_TEST_HELPER_H__ #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -86,8 +83,8 @@ class TypeInfoTestHelper { private: TypeInfoSource type_; - google::protobuf::scoped_ptr typeinfo_; - google::protobuf::scoped_ptr type_resolver_; + std::unique_ptr typeinfo_; + std::unique_ptr type_resolver_; }; } // namespace testing } // namespace converter diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index b1007765..b8d917ce 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -52,7 +52,7 @@ bool GetBoolOptionOrDefault( const google::protobuf::RepeatedPtrField& options, const string& option_name, bool default_value) { const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); - if (opt == NULL) { + if (opt == nullptr) { return default_value; } return GetBoolFromAny(opt->value()); @@ -62,7 +62,7 @@ int64 GetInt64OptionOrDefault( const google::protobuf::RepeatedPtrField& options, const string& option_name, int64 default_value) { const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); - if (opt == NULL) { + if (opt == nullptr) { return default_value; } return GetInt64FromAny(opt->value()); @@ -72,7 +72,7 @@ double GetDoubleOptionOrDefault( const google::protobuf::RepeatedPtrField& options, const string& option_name, double default_value) { const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); - if (opt == NULL) { + if (opt == nullptr) { return default_value; } return GetDoubleFromAny(opt->value()); @@ -82,7 +82,7 @@ string GetStringOptionOrDefault( const google::protobuf::RepeatedPtrField& options, const string& option_name, const string& default_value) { const google::protobuf::Option* opt = FindOptionOrNull(options, option_name); - if (opt == NULL) { + if (opt == nullptr) { return default_value; } return GetStringFromAny(opt->value()); @@ -144,12 +144,12 @@ const google::protobuf::Option* FindOptionOrNull( return &opt; } } - return NULL; + return nullptr; } const google::protobuf::Field* FindFieldInTypeOrNull( const google::protobuf::Type* type, StringPiece field_name) { - if (type != NULL) { + if (type != nullptr) { for (int i = 0; i < type->fields_size(); ++i) { const google::protobuf::Field& field = type->fields(i); if (field.name() == field_name) { @@ -157,12 +157,12 @@ const google::protobuf::Field* FindFieldInTypeOrNull( } } } - return NULL; + return nullptr; } const google::protobuf::Field* FindJsonFieldInTypeOrNull( const google::protobuf::Type* type, StringPiece json_name) { - if (type != NULL) { + if (type != nullptr) { for (int i = 0; i < type->fields_size(); ++i) { const google::protobuf::Field& field = type->fields(i); if (field.json_name() == json_name) { @@ -170,12 +170,12 @@ const google::protobuf::Field* FindJsonFieldInTypeOrNull( } } } - return NULL; + return nullptr; } const google::protobuf::Field* FindFieldInTypeByNumberOrNull( const google::protobuf::Type* type, int32 number) { - if (type != NULL) { + if (type != nullptr) { for (int i = 0; i < type->fields_size(); ++i) { const google::protobuf::Field& field = type->fields(i); if (field.number() == number) { @@ -183,12 +183,12 @@ const google::protobuf::Field* FindFieldInTypeByNumberOrNull( } } } - return NULL; + return nullptr; } const google::protobuf::EnumValue* FindEnumValueByNameOrNull( const google::protobuf::Enum* enum_type, StringPiece enum_name) { - if (enum_type != NULL) { + if (enum_type != nullptr) { for (int i = 0; i < enum_type->enumvalue_size(); ++i) { const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); if (enum_value.name() == enum_name) { @@ -196,12 +196,12 @@ const google::protobuf::EnumValue* FindEnumValueByNameOrNull( } } } - return NULL; + return nullptr; } const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( const google::protobuf::Enum* enum_type, int32 value) { - if (enum_type != NULL) { + if (enum_type != nullptr) { for (int i = 0; i < enum_type->enumvalue_size(); ++i) { const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); if (enum_value.number() == value) { @@ -209,12 +209,12 @@ const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( } } } - return NULL; + return nullptr; } const google::protobuf::EnumValue* FindEnumValueByNameWithoutUnderscoreOrNull( const google::protobuf::Enum* enum_type, StringPiece enum_name) { - if (enum_type != NULL) { + if (enum_type != nullptr) { for (int i = 0; i < enum_type->enumvalue_size(); ++i) { const google::protobuf::EnumValue& enum_value = enum_type->enumvalue(i); string enum_name_without_underscore = enum_value.name(); @@ -235,7 +235,14 @@ const google::protobuf::EnumValue* FindEnumValueByNameWithoutUnderscoreOrNull( } } } - return NULL; + return nullptr; +} + +string EnumValueNameToLowerCamelCase(const StringPiece input) { + string input_string(input); + std::transform(input_string.begin(), input_string.end(), input_string.begin(), + ::tolower); + return ToCamelCase(input_string); } string ToCamelCase(const StringPiece input) { @@ -398,6 +405,13 @@ bool SafeStrToFloat(StringPiece str, float* value) { return true; } +bool StringStartsWith(StringPiece text, StringPiece prefix) { + return text.starts_with(prefix); +} + +bool StringEndsWith(StringPiece text, StringPiece suffix) { + return text.ends_with(suffix); +} } // namespace converter } // namespace util } // namespace protobuf diff --git a/src/google/protobuf/util/internal/utility.h b/src/google/protobuf/util/internal/utility.h index 667e660c..d8e06a97 100644 --- a/src/google/protobuf/util/internal/utility.h +++ b/src/google/protobuf/util/internal/utility.h @@ -32,9 +32,6 @@ #define GOOGLE_PROTOBUF_UTIL_CONVERTER_UTILITY_H__ #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -121,13 +118,13 @@ LIBPROTOBUF_EXPORT const StringPiece GetTypeWithoutUrl(StringPiece type_url); LIBPROTOBUF_EXPORT const string GetFullTypeWithUrl(StringPiece simple_type); // Finds and returns option identified by name and option_name within the -// provided map. Returns NULL if none found. +// provided map. Returns nullptr if none found. const google::protobuf::Option* FindOptionOrNull( const google::protobuf::RepeatedPtrField& options, const string& option_name); // Finds and returns the field identified by field_name in the passed tech Type -// object. Returns NULL if none found. +// object. Returns nullptr if none found. const google::protobuf::Field* FindFieldInTypeOrNull( const google::protobuf::Type* type, StringPiece field_name); @@ -141,17 +138,17 @@ const google::protobuf::Field* FindFieldInTypeByNumberOrNull( const google::protobuf::Type* type, int32 number); // Finds and returns the EnumValue identified by enum_name in the passed tech -// Enum object. Returns NULL if none found. +// Enum object. Returns nullptr if none found. const google::protobuf::EnumValue* FindEnumValueByNameOrNull( const google::protobuf::Enum* enum_type, StringPiece enum_name); // Finds and returns the EnumValue identified by value in the passed tech -// Enum object. Returns NULL if none found. +// Enum object. Returns nullptr if none found. const google::protobuf::EnumValue* FindEnumValueByNumberOrNull( const google::protobuf::Enum* enum_type, int32 value); // Finds and returns the EnumValue identified by enum_name without underscore in -// the passed tech Enum object. Returns NULL if none found. +// the passed tech Enum object. Returns nullptr if none found. // For Ex. if enum_name is ACTIONANDADVENTURE it can get accepted if // EnumValue's name is action_and_adventure or ACTION_AND_ADVENTURE. const google::protobuf::EnumValue* FindEnumValueByNameWithoutUnderscoreOrNull( @@ -160,6 +157,9 @@ const google::protobuf::EnumValue* FindEnumValueByNameWithoutUnderscoreOrNull( // Converts input to camel-case and returns it. LIBPROTOBUF_EXPORT string ToCamelCase(const StringPiece input); +// Converts enum name string to camel-case and returns it. +string EnumValueNameToLowerCamelCase(const StringPiece input); + // Converts input to snake_case and returns it. LIBPROTOBUF_EXPORT string ToSnakeCase(StringPiece input); @@ -200,6 +200,12 @@ inline string ValueAsString(double value) { // Converts a string to float. Unlike safe_strtof, conversion will fail if the // value fits into double but not float (e.g., DBL_MAX). LIBPROTOBUF_EXPORT bool SafeStrToFloat(StringPiece str, float* value); + +// Returns whether a StringPiece begins with the provided prefix. +bool StringStartsWith(StringPiece text, StringPiece prefix); + +// Returns whether a StringPiece ends with the provided suffix. +bool StringEndsWith(StringPiece text, StringPiece suffix); } // namespace converter } // namespace util } // namespace protobuf diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc index 25e78a65..ea0cc2e4 100644 --- a/src/google/protobuf/util/json_util.cc +++ b/src/google/protobuf/util/json_util.cc @@ -125,22 +125,22 @@ class StatusErrorListener : public converter::ErrorListener { virtual void InvalidName(const converter::LocationTrackerInterface& loc, StringPiece unknown_name, StringPiece message) { status_ = util::Status(util::error::INVALID_ARGUMENT, - loc.ToString() + ": " + message.ToString()); + loc.ToString() + ": " + string(message)); } virtual void InvalidValue(const converter::LocationTrackerInterface& loc, StringPiece type_name, StringPiece value) { status_ = util::Status(util::error::INVALID_ARGUMENT, - loc.ToString() + ": invalid value " + value.ToString() + - " for type " + type_name.ToString()); + loc.ToString() + ": invalid value " + string(value) + + " for type " + string(type_name)); } virtual void MissingField(const converter::LocationTrackerInterface& loc, StringPiece missing_name) { status_ = util::Status( util::error::INVALID_ARGUMENT, - loc.ToString() + ": missing field " + missing_name.ToString()); + loc.ToString() + ": missing field " + string(missing_name)); } private: diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc index 5b714bb1..8c8380dc 100644 --- a/src/google/protobuf/util/json_util_test.cc +++ b/src/google/protobuf/util/json_util_test.cc @@ -34,13 +34,13 @@ #include #include +#include #include #include #include #include #include #include -#include #include namespace google { @@ -48,12 +48,12 @@ namespace protobuf { namespace util { namespace { +using google::protobuf::testing::MapIn; using proto3::FOO; using proto3::BAR; using proto3::TestMessage; using proto3::TestMap; using proto3::TestOneof; -using google::protobuf::testing::MapIn; static const char kTypeUrlPrefix[] = "type.googleapis.com"; @@ -82,7 +82,7 @@ class JsonUtilTest : public ::testing::Test { return FromJson(json, message, JsonParseOptions()); } - google::protobuf::scoped_ptr resolver_; + std::unique_ptr resolver_; }; TEST_F(JsonUtilTest, TestWhitespaces) { @@ -313,7 +313,7 @@ TEST_F(JsonUtilTest, TestDynamicMessage) { DescriptorPool pool(&database); // A dynamic version of the test proto. DynamicMessageFactory factory; - google::protobuf::scoped_ptr message(factory.GetPrototype( + std::unique_ptr message(factory.GetPrototype( pool.FindMessageTypeByName("proto3.TestMessage"))->New()); EXPECT_TRUE(FromJson(input, message.get())); @@ -459,26 +459,22 @@ TEST(ZeroCopyStreamByteSinkTest, TestAllInputOutputPatterns) { } TEST_F(JsonUtilTest, TestWrongJsonInput) { - using namespace google::protobuf; const char json[] = "{\"unknown_field\":\"some_value\"}"; io::ArrayInputStream input_stream(json, strlen(json)); char proto_buffer[10000]; io::ArrayOutputStream output_stream(proto_buffer, sizeof(proto_buffer)); - std::string message_type = "type.googleapis.com/proto3.TestMessage"; + std::string message_type = "type.googleapis.com/proto3.TestMessage"; TypeResolver* resolver = NewTypeResolverForDescriptorPool( - "type.googleapis.com", - DescriptorPool::generated_pool()); - - util::Status result_status = util::JsonToBinaryStream(resolver, - message_type, - &input_stream, - &output_stream); - + "type.googleapis.com", DescriptorPool::generated_pool()); + + auto result_status = util::JsonToBinaryStream( + resolver, message_type, &input_stream, &output_stream); + delete resolver; EXPECT_FALSE(result_status.ok()); - EXPECT_EQ(result_status.error_code(), - google::protobuf::util::error::INVALID_ARGUMENT); + EXPECT_EQ(result_status.error_code(), + util::error::INVALID_ARGUMENT); } } // namespace diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index c32e941c..9842f64c 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -40,9 +40,6 @@ #include #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -490,8 +487,8 @@ bool MessageDifferencer::Compare( } // Expand google.protobuf.Any payload if possible. if (descriptor1->full_name() == internal::kAnyFullTypeName) { - google::protobuf::scoped_ptr data1; - google::protobuf::scoped_ptr data2; + std::unique_ptr data1; + std::unique_ptr data2; if (UnpackAny(message1, &data1) && UnpackAny(message2, &data2)) { // Avoid DFATAL for different descriptors in google.protobuf.Any payloads. if (data1->GetDescriptor() != data2->GetDescriptor()) { @@ -1068,7 +1065,7 @@ struct UnknownFieldOrdering { } // namespace bool MessageDifferencer::UnpackAny(const Message& any, - google::protobuf::scoped_ptr* data) { + std::unique_ptr* data) { const Reflection* reflection = any.GetReflection(); const FieldDescriptor* type_url_field; const FieldDescriptor* value_field; @@ -1341,7 +1338,7 @@ class MaximumMatcher { int count1_; int count2_; - google::protobuf::scoped_ptr match_callback_; + std::unique_ptr match_callback_; std::map, bool> cached_match_results_; std::vector* match_list1_; std::vector* match_list2_; @@ -1459,11 +1456,27 @@ bool MessageDifferencer::MatchRepeatedFieldIndices( if (match_count != count1 && reporter_ == NULL) return false; success = success && (match_count == count1); } else { - for (int i = 0; i < count1; ++i) { + int start_offset = 0; + // If the two repeated fields are treated as sets, optimize for the case + // where both start with same items stored in the same order. + if (IsTreatedAsSet(repeated_field)) { + start_offset = std::min(count1, count2); + for (int i = 0; i < count1 && i < count2; i++) { + if (IsMatch(repeated_field, key_comparator, &message1, &message2, + parent_fields, i, i)) { + match_list1->at(i) = i; + match_list2->at(i) = i; + } else { + start_offset = i; + break; + } + } + } + for (int i = start_offset; i < count1; ++i) { // Indicates any matched elements for this repeated field. bool match = false; - for (int j = 0; j < count2; j++) { + for (int j = start_offset; j < count2; j++) { if (match_list2->at(j) != -1) continue; match = IsMatch(repeated_field, key_comparator, diff --git a/src/google/protobuf/util/message_differencer.h b/src/google/protobuf/util/message_differencer.h index 11d6cc03..bbcf8498 100644 --- a/src/google/protobuf/util/message_differencer.h +++ b/src/google/protobuf/util/message_differencer.h @@ -175,10 +175,8 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { // If "field" is a repeated field which is being treated as a map or // a set (see TreatAsMap() and TreatAsSet(), below), new_index indicates - // the index the position to which the element has moved. This only - // applies to ReportMoved() and (in the case of TreatAsMap()) - // ReportModified(). In all other cases, "new_index" will have the same - // value as "index". + // the index the position to which the element has moved. If the element + // has not moved, "new_index" will have the same value as "index". int new_index; // For unknown fields, these are the pointers to the UnknownFieldSet @@ -823,7 +821,7 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { // If "any" is of type google.protobuf.Any, extract its payload using // DynamicMessageFactory and store in "data". - bool UnpackAny(const Message& any, google::protobuf::scoped_ptr* data); + bool UnpackAny(const Message& any, std::unique_ptr* data); // Checks if index is equal to new_index in all the specific fields. static bool CheckPathChanged(const std::vector& parent_fields); @@ -864,7 +862,7 @@ class LIBPROTOBUF_EXPORT MessageDifferencer { string* output_string_; - google::protobuf::scoped_ptr dynamic_message_factory_; + std::unique_ptr dynamic_message_factory_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageDifferencer); }; diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc index 75cffd9f..a263d983 100755 --- a/src/google/protobuf/util/message_differencer_unittest.cc +++ b/src/google/protobuf/util/message_differencer_unittest.cc @@ -127,6 +127,27 @@ TEST(MessageDifferencerTest, RepeatedFieldInequalityTest) { EXPECT_FALSE(util::MessageDifferencer::Equals(msg1, msg2)); } +TEST(MessageDifferencerTest, RepeatedFieldSetOptimizationTest) { + util::MessageDifferencer differencer; + protobuf_unittest::TestDiffMessage msg1; + protobuf_unittest::TestDiffMessage msg2; + protobuf_unittest::TestDiffMessage::Item* item1 = msg1.add_item(); + protobuf_unittest::TestDiffMessage::Item* item2 = msg2.add_item(); + differencer.TreatAsSet(item1->GetDescriptor()->FindFieldByName("ra")); + differencer.TreatAsSet(item2->GetDescriptor()->FindFieldByName("ra")); + for (int i = 0; i < 1000; i++) { + item1->add_ra(i); + item2->add_ra(i); + } + EXPECT_TRUE(differencer.Compare(msg1, msg2)); + item2->add_ra(1001); + EXPECT_FALSE(differencer.Compare(msg1, msg2)); + item1->add_ra(1001); + EXPECT_TRUE(differencer.Compare(msg1, msg2)); + item1->add_ra(1002); + EXPECT_FALSE(differencer.Compare(msg1, msg2)); +} + TEST(MessageDifferencerTest, MapFieldEqualityTest) { // Create the testing protos unittest::TestMap msg1; diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc index 46a6f5a8..d4912837 100644 --- a/src/google/protobuf/util/time_util.cc +++ b/src/google/protobuf/util/time_util.cc @@ -30,13 +30,14 @@ #include -#include #include -#include #include +#include +#include #include #include + namespace google { namespace protobuf { namespace util { diff --git a/src/google/protobuf/util/type_resolver_util.cc b/src/google/protobuf/util/type_resolver_util.cc index febaa41f..a69ed58c 100644 --- a/src/google/protobuf/util/type_resolver_util.cc +++ b/src/google/protobuf/util/type_resolver_util.cc @@ -95,11 +95,6 @@ class DescriptorPoolTypeResolver : public TypeResolver { type->Clear(); type->set_name(descriptor->full_name()); for (int i = 0; i < descriptor->field_count(); ++i) { - const FieldDescriptor* field = descriptor->field(i); - if (field->type() == FieldDescriptor::TYPE_GROUP) { - // Group fields cannot be represented with Type. We discard them. - continue; - } ConvertFieldDescriptor(descriptor->field(i), type->add_fields()); } for (int i = 0; i < descriptor->oneof_decl_count(); ++i) { @@ -141,7 +136,8 @@ class DescriptorPoolTypeResolver : public TypeResolver { if (descriptor->has_default_value()) { field->set_default_value(DefaultValueAsString(descriptor)); } - if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE) { + if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE || + descriptor->type() == FieldDescriptor::TYPE_GROUP) { field->set_type_url(GetTypeUrl(descriptor->message_type())); } else if (descriptor->type() == FieldDescriptor::TYPE_ENUM) { field->set_type_url(GetTypeUrl(descriptor->enum_type())); diff --git a/src/google/protobuf/util/type_resolver_util_test.cc b/src/google/protobuf/util/type_resolver_util_test.cc index 8a0bf652..9dea17ae 100644 --- a/src/google/protobuf/util/type_resolver_util_test.cc +++ b/src/google/protobuf/util/type_resolver_util_test.cc @@ -32,9 +32,6 @@ #include #include -#ifndef _SHARED_PTR_H -#include -#endif #include #include @@ -153,7 +150,7 @@ class DescriptorPoolTypeResolverTest : public testing::Test { } protected: - google::protobuf::scoped_ptr resolver_; + std::unique_ptr resolver_; }; TEST_F(DescriptorPoolTypeResolverTest, TestAllTypes) { @@ -192,6 +189,13 @@ TEST_F(DescriptorPoolTypeResolverTest, TestAllTypes) { EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_BYTES, "optional_bytes", 15)); + EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, + Field::TYPE_GROUP, "optionalgroup", 16)); + + EXPECT_TRUE(CheckFieldTypeUrl( + type, "optionalgroup", + GetTypeUrl())); + EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, Field::TYPE_MESSAGE, "optional_nested_message", 18)); EXPECT_TRUE(HasField(type, Field::CARDINALITY_OPTIONAL, @@ -248,6 +252,13 @@ TEST_F(DescriptorPoolTypeResolverTest, TestAllTypes) { EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_BYTES, "repeated_bytes", 45)); + EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, + Field::TYPE_GROUP, "repeatedgroup", 46)); + + EXPECT_TRUE(CheckFieldTypeUrl( + type, "repeatedgroup", + GetTypeUrl())); + EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, Field::TYPE_MESSAGE, "repeated_nested_message", 48)); EXPECT_TRUE(HasField(type, Field::CARDINALITY_REPEATED, @@ -271,13 +282,6 @@ TEST_F(DescriptorPoolTypeResolverTest, TestAllTypes) { EXPECT_TRUE(CheckFieldTypeUrl( type, "repeated_foreign_enum", GetTypeUrl("protobuf_unittest.ForeignEnum"))); - - // Groups are discarded when converting to Type. - const Descriptor* descriptor = protobuf_unittest::TestAllTypes::descriptor(); - EXPECT_TRUE(descriptor->FindFieldByName("optionalgroup") != NULL); - EXPECT_TRUE(descriptor->FindFieldByName("repeatedgroup") != NULL); - ASSERT_FALSE(HasField(type, "optionalgroup")); - ASSERT_FALSE(HasField(type, "repeatedgroup")); } TEST_F(DescriptorPoolTypeResolverTest, TestPackedField) { -- cgit v1.2.3