aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/util/internal/default_value_objectwriter.cc
diff options
context:
space:
mode:
authorGravatar Feng Xiao <xfxyjwf@gmail.com>2015-08-22 18:25:48 -0700
committerGravatar Feng Xiao <xfxyjwf@gmail.com>2015-08-22 18:25:48 -0700
commiteee38b0c018b3279f77d03dff796f440f40d3516 (patch)
tree7ff0978e30238d493fc7899b75abeb6d66939f07 /src/google/protobuf/util/internal/default_value_objectwriter.cc
parentc3bc155aceda36ecb01cde2367a3b427f2d7ce40 (diff)
Down-integrate from google3.
Diffstat (limited to 'src/google/protobuf/util/internal/default_value_objectwriter.cc')
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.cc66
1 files changed, 43 insertions, 23 deletions
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<Node> 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> node(
new Node(name.ToString(), NULL, PRIMITIVE, data, false));