From eee38b0c018b3279f77d03dff796f440f40d3516 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Sat, 22 Aug 2015 18:25:48 -0700 Subject: Down-integrate from google3. --- .../util/internal/default_value_objectwriter.cc | 66 ++++++++++++++-------- 1 file changed, 43 insertions(+), 23 deletions(-) (limited to 'src/google/protobuf/util/internal/default_value_objectwriter.cc') diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index 267e2cd3..97b248ff 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -46,6 +46,7 @@ DefaultValueObjectWriter::DefaultValueObjectWriter( TypeResolver* type_resolver, const google::protobuf::Type& type, ObjectWriter* ow) : typeinfo_(TypeInfo::NewTypeInfo(type_resolver)), + own_typeinfo_(true), type_(type), disable_normalize_(false), current_(NULL), @@ -56,6 +57,9 @@ DefaultValueObjectWriter::~DefaultValueObjectWriter() { for (int i = 0; i < string_values_.size(); ++i) { delete string_values_[i]; } + if (own_typeinfo_) { + delete typeinfo_; + } } DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBool(StringPiece name, @@ -197,33 +201,47 @@ void DefaultValueObjectWriter::Node::WriteTo(ObjectWriter* ow) { if (disable_normalize_) { ow->DisableCaseNormalizationForNextKey(); } + if (kind_ == PRIMITIVE) { ObjectWriter::RenderDataPieceTo(data_, name_, ow); return; } - if (is_placeholder_) { - // If is_placeholder_ = true, we didn't see this node in the response, so - // skip output. + + // Render maps. Empty maps are rendered as "{}". + if (kind_ == MAP) { + ow->StartObject(name_); + WriteChildren(ow); + ow->EndObject(); return; } + + // Write out lists. If we didn't have any list in response, write out empty + // list. if (kind_ == LIST) { ow->StartList(name_); - } else { - ow->StartObject(name_); + WriteChildren(ow); + ow->EndList(); + return; } + + // If is_placeholder_ = true, we didn't see this node in the response, so + // skip output. + if (is_placeholder_) return; + + ow->StartObject(name_); + WriteChildren(ow); + ow->EndObject(); +} + +void DefaultValueObjectWriter::Node::WriteChildren(ObjectWriter* ow) { for (int i = 0; i < children_.size(); ++i) { Node* child = children_[i]; child->WriteTo(ow); } - if (kind_ == LIST) { - ow->EndList(); - } else { - ow->EndObject(); - } } const google::protobuf::Type* DefaultValueObjectWriter::Node::GetMapValueType( - const google::protobuf::Type& found_type, TypeInfo* typeinfo) { + const google::protobuf::Type& found_type, const TypeInfo* typeinfo) { // If this field is a map, we should use the type of its "Value" as // the type of the child node. for (int i = 0; i < found_type.fields_size(); ++i) { @@ -248,7 +266,8 @@ const google::protobuf::Type* DefaultValueObjectWriter::Node::GetMapValueType( return NULL; } -void DefaultValueObjectWriter::Node::PopulateChildren(TypeInfo* typeinfo) { +void DefaultValueObjectWriter::Node::PopulateChildren( + const TypeInfo* typeinfo) { // Ignores well known types that don't require automatically populating their // primitive children. For type "Any", we only populate its children when the // "@type" field is set. @@ -310,15 +329,17 @@ void DefaultValueObjectWriter::Node::PopulateChildren(TypeInfo* typeinfo) { google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) { kind = LIST; } - // If the child field is of primitive type, sets its data to the default - // value of its type. + // If oneof_index() != 0, the child field is part of a "oneof", which means // the child field is optional and we shouldn't populate its default value. + if (field.oneof_index() != 0) continue; + + // 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(field.name(), field_type, kind, - ((kind == PRIMITIVE && field.oneof_index() == 0) - ? CreateDefaultDataPieceForField(field) - : DataPiece::NullData()), + new Node(field.json_name(), field_type, kind, + kind == PRIMITIVE ? CreateDefaultDataPieceForField(field) + : DataPiece::NullData(), true)); new_children.push_back(child.release()); } @@ -338,7 +359,7 @@ void DefaultValueObjectWriter::MaybePopulateChildrenOfAny(Node* node) { // have been added, populates its children. if (node != NULL && node->is_any() && node->type() != NULL && node->type()->name() != kAnyType && node->number_of_children() == 1) { - node->PopulateChildren(typeinfo_.get()); + node->PopulateChildren(typeinfo_); } } @@ -388,7 +409,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(), false)); root_->set_disable_normalize(GetAndResetDisableNormalize()); - root_->PopulateChildren(typeinfo_.get()); + root_->PopulateChildren(typeinfo_); current_ = root_.get(); return this; } @@ -409,7 +430,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( child->set_is_placeholder(false); child->set_disable_normalize(GetAndResetDisableNormalize()); if (child->kind() == OBJECT && child->number_of_children() == 0) { - child->PopulateChildren(typeinfo_.get()); + child->PopulateChildren(typeinfo_); } stack_.push(current_); @@ -492,12 +513,11 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, // 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) { - current_->PopulateChildren(typeinfo_.get()); + current_->PopulateChildren(typeinfo_); } } Node* child = current_->FindChild(name); if (child == NULL || child->kind() != PRIMITIVE) { - GOOGLE_LOG(WARNING) << "Cannot find primitive field '" << name << "'."; // No children are found, creates a new child. google::protobuf::scoped_ptr node( new Node(name.ToString(), NULL, PRIMITIVE, data, false)); -- cgit v1.2.3