diff options
Diffstat (limited to 'src/google/protobuf/util')
20 files changed, 268 insertions, 255 deletions
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index b33ad206..5763d0c6 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -189,6 +189,39 @@ void DefaultValueObjectWriter::RegisterFieldScrubCallBack( field_scrub_callback_.reset(field_scrub_callback.release()); } +DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode( + const string& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, const std::vector<string>& path, + bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback) { + return new Node(name, type, kind, data, is_placeholder, path, + suppress_empty_list, field_scrub_callback); +} + +DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode( + const string& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, const std::vector<string>& path, + bool suppress_empty_list, bool preserve_proto_field_names, + FieldScrubCallBack* field_scrub_callback) { + return new Node(name, type, kind, data, is_placeholder, path, + suppress_empty_list, preserve_proto_field_names, + field_scrub_callback); +} + +DefaultValueObjectWriter::Node::Node( + const string& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, const std::vector<string>& path, + bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback) + : name_(name), + type_(type), + kind_(kind), + is_any_(false), + data_(data), + is_placeholder_(is_placeholder), + path_(path), + suppress_empty_list_(suppress_empty_list), + preserve_proto_field_names_(false), + field_scrub_callback_(field_scrub_callback) {} + DefaultValueObjectWriter::Node::Node( const string& name, const google::protobuf::Type* type, NodeKind kind, const DataPiece& data, bool is_placeholder, const std::vector<string>& path, @@ -473,10 +506,10 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( StringPiece name) { if (current_ == NULL) { std::vector<string> path; - root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(), - false, path, suppress_empty_list_, - preserve_proto_field_names_, - field_scrub_callback_.get())); + root_.reset(CreateNewNode(string(name), &type_, OBJECT, + DataPiece::NullData(), false, path, + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); root_->PopulateChildren(typeinfo_); current_ = root_.get(); return this; @@ -486,14 +519,15 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( if (current_->kind() == LIST || current_->kind() == MAP || child == NULL) { // 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> node(new Node( - name.ToString(), ((current_->kind() == LIST || current_->kind() == MAP) - ? current_->type() - : NULL), - OBJECT, DataPiece::NullData(), false, - child == NULL ? current_->path() : child->path(), - suppress_empty_list_, preserve_proto_field_names_, - field_scrub_callback_.get())); + google::protobuf::scoped_ptr<Node> node( + CreateNewNode(string(name), + ((current_->kind() == LIST || current_->kind() == MAP) + ? current_->type() + : NULL), + OBJECT, DataPiece::NullData(), false, + child == NULL ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); child = node.get(); current_->AddChild(node.release()); } @@ -523,10 +557,10 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( StringPiece name) { if (current_ == NULL) { std::vector<string> path; - root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(), - false, path, suppress_empty_list_, - preserve_proto_field_names_, - field_scrub_callback_.get())); + root_.reset(CreateNewNode(string(name), &type_, LIST, DataPiece::NullData(), + false, path, suppress_empty_list_, + preserve_proto_field_names_, + field_scrub_callback_.get())); current_ = root_.get(); return this; } @@ -534,10 +568,10 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( Node* child = current_->FindChild(name); if (child == NULL || child->kind() != LIST) { google::protobuf::scoped_ptr<Node> node( - new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false, - child == NULL ? current_->path() : child->path(), - suppress_empty_list_, preserve_proto_field_names_, - field_scrub_callback_.get())); + CreateNewNode(string(name), NULL, LIST, DataPiece::NullData(), false, + child == NULL ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); child = node.get(); current_->AddChild(node.release()); } @@ -596,10 +630,10 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, if (child == NULL || child->kind() != PRIMITIVE) { // No children are found, creates a new child. google::protobuf::scoped_ptr<Node> node( - new Node(name.ToString(), NULL, PRIMITIVE, data, false, - child == NULL ? current_->path() : child->path(), - suppress_empty_list_, preserve_proto_field_names_, - field_scrub_callback_.get())); + CreateNewNode(string(name), NULL, PRIMITIVE, data, false, + child == NULL ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); current_->AddChild(node.release()); } else { child->set_data(data); diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h index ddf23594..ef2cc981 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.h +++ b/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -127,9 +127,11 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; } // If set to true, original proto field names are used - void set_preserve_proto_field_names(bool value) { preserve_proto_field_names_ = value; } + void set_preserve_proto_field_names(bool value) { + preserve_proto_field_names_ = value; + } - private: + protected: enum NodeKind { PRIMITIVE = 0, OBJECT = 1, @@ -144,7 +146,12 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { Node(const string& name, const google::protobuf::Type* type, NodeKind kind, const DataPiece& data, bool is_placeholder, const std::vector<string>& path, bool suppress_empty_list, - bool preserve_proto_field_names, FieldScrubCallBack* field_scrub_callback); + FieldScrubCallBack* field_scrub_callback); + Node(const string& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector<string>& path, bool suppress_empty_list, + bool preserve_proto_field_names, + FieldScrubCallBack* field_scrub_callback); virtual ~Node() { for (int i = 0; i < children_.size(); ++i) { delete children_[i]; @@ -160,7 +167,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // Populates children of this Node based on its type. If there are already // children created, they will be merged to the result. Caller should pass // in TypeInfo for looking up types of the children. - void PopulateChildren(const TypeInfo* typeinfo); + virtual void PopulateChildren(const TypeInfo* typeinfo); // If this node is a leaf (has data), writes the current node to the // ObjectWriter; if not, then recursively writes the children to the @@ -190,7 +197,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { is_placeholder_ = is_placeholder; } - private: + protected: // Returns the Value Type of a map given the Type of the map entry and a // TypeInfo instance. const google::protobuf::Type* GetMapValueType( @@ -230,9 +237,32 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // or not. This callback is owned by the creator of this node. FieldScrubCallBack* field_scrub_callback_; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node); }; + // Creates a new Node and returns it. Caller owns memory of returned object. + virtual Node* CreateNewNode(const string& name, + const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector<string>& path, + bool suppress_empty_list, + FieldScrubCallBack* field_scrub_callback); + + // Creates a new Node and returns it. Caller owns memory of returned object. + virtual Node* CreateNewNode(const string& name, + const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector<string>& path, + bool suppress_empty_list, + bool preserve_proto_field_names, + FieldScrubCallBack* field_scrub_callback); + + // Creates a DataPiece containing the default value of the type of the field. + static DataPiece CreateDefaultDataPieceForField( + const google::protobuf::Field& field, const TypeInfo* typeinfo); + + private: // Populates children of "node" if it is an "any" Node and its real type has // been given. void MaybePopulateChildrenOfAny(Node* node); @@ -241,10 +271,6 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // NULL. void WriteRoot(); - // Creates a DataPiece containing the default value of the type of the field. - static DataPiece CreateDefaultDataPieceForField( - const google::protobuf::Field& field, const TypeInfo* typeinfo); - // Adds or replaces the data_ of a primitive child node. void RenderDataPiece(StringPiece name, const DataPiece& data); diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc index 53b90fb0..38835f67 100644 --- a/src/google/protobuf/util/internal/field_mask_utility.cc +++ b/src/google/protobuf/util/internal/field_mask_utility.cc @@ -44,11 +44,6 @@ inline util::Status CallPathSink(PathSinkCallback path_sink, return path_sink->Run(arg); } -util::Status CreatePublicError(util::error::Code code, - const string& message) { - return util::Status(code, message); -} - // Appends a FieldMask path segment to a prefix. string AppendPathSegmentToPrefix(StringPiece prefix, StringPiece segment) { if (prefix.empty()) { @@ -216,7 +211,7 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths, StrCat("Invalid FieldMask '", paths, "'. Cannot find matching ')' for all '('.")); } - return util::Status::OK; + return util::Status(); } } // namespace converter diff --git a/src/google/protobuf/util/internal/json_escaping.cc b/src/google/protobuf/util/internal/json_escaping.cc index 47e4dd6d..18b7f923 100644 --- a/src/google/protobuf/util/internal/json_escaping.cc +++ b/src/google/protobuf/util/internal/json_escaping.cc @@ -84,30 +84,6 @@ static const char kCommonEscapes[160][7] = { "\\u009c", "\\u009d", "\\u009e", "\\u009f" }; -// Determines if the given char value is a unicode high-surrogate code unit. -// Such values do not represent characters by themselves, but are used in the -// representation of supplementary characters in the utf-16 encoding. -inline bool IsHighSurrogate(uint16 c) { - // Optimized form of: - // return c >= kMinHighSurrogate && c <= kMaxHighSurrogate; - // (Reduced from 3 ALU instructions to 2 ALU instructions) - return (c & ~(JsonEscaping::kMaxHighSurrogate - - JsonEscaping::kMinHighSurrogate)) - == JsonEscaping::kMinHighSurrogate; -} - -// Determines if the given char value is a unicode low-surrogate code unit. -// Such values do not represent characters by themselves, but are used in the -// representation of supplementary characters in the utf-16 encoding. -inline bool IsLowSurrogate(uint16 c) { - // Optimized form of: - // return c >= kMinLowSurrogate && c <= kMaxLowSurrogate; - // (Reduced from 3 ALU instructions to 2 ALU instructions) - return (c & ~(JsonEscaping::kMaxLowSurrogate - - JsonEscaping::kMinLowSurrogate)) - == JsonEscaping::kMinLowSurrogate; -} - // Determines if the given char value is a unicode surrogate code unit (either // high-surrogate or low-surrogate). inline bool IsSurrogate(uint32 c) { @@ -117,36 +93,12 @@ inline bool IsSurrogate(uint32 c) { return (c & 0xfffff800) == JsonEscaping::kMinHighSurrogate; } -// Returns true if the given unicode code point cp is -// in the supplementary character range. -inline bool IsSupplementalCodePoint(uint32 cp) { - // Optimized form of: - // return kMinSupplementaryCodePoint <= cp && cp <= kMaxCodePoint; - // (Reduced from 3 ALU instructions to 2 ALU instructions) - return (cp & ~(JsonEscaping::kMinSupplementaryCodePoint - 1)) - < JsonEscaping::kMaxCodePoint; -} - // Returns true if the given unicode code point cp is a valid // unicode code point (i.e. in the range 0 <= cp <= kMaxCodePoint). inline bool IsValidCodePoint(uint32 cp) { return cp <= JsonEscaping::kMaxCodePoint; } -// Converts the specified surrogate pair to its supplementary code point value. -// It is the callers' responsibility to validate the specified surrogate pair. -inline uint32 ToCodePoint(uint16 high, uint16 low) { - // Optimized form of: - // return ((high - kMinHighSurrogate) << 10) - // + (low - kMinLowSurrogate) - // + kMinSupplementaryCodePoint; - // (Reduced from 5 ALU instructions to 3 ALU instructions) - return (high << 10) + low + - (JsonEscaping::kMinSupplementaryCodePoint - - (static_cast<unsigned>(JsonEscaping::kMinHighSurrogate) << 10) - - JsonEscaping::kMinLowSurrogate); -} - // Returns the low surrogate for the given unicode code point. The result is // meaningless if the given code point is not a supplementary character. inline uint16 ToLowSurrogate(uint32 cp) { diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc index b38030c3..047c14e1 100644 --- a/src/google/protobuf/util/internal/json_stream_parser.cc +++ b/src/google/protobuf/util/internal/json_stream_parser.cc @@ -130,7 +130,7 @@ util::Status JsonStreamParser::Parse(StringPiece json) { // Don't point chunk to leftover_ because leftover_ will be updated in // ParseChunk(chunk). chunk_storage_.swap(leftover_); - json.AppendToString(&chunk_storage_); + StrAppend(&chunk_storage_, json); chunk = StringPiece(chunk_storage_); } @@ -141,11 +141,11 @@ util::Status JsonStreamParser::Parse(StringPiece json) { // Any leftover characters are stashed in leftover_ for later parsing when // there is more data available. - chunk.substr(n).AppendToString(&leftover_); + StrAppend(&leftover_, chunk.substr(n)); return status; } else { - chunk.CopyToString(&leftover_); - return util::Status::OK; + leftover_.assign(chunk.data(), chunk.size()); + return util::Status(); } } @@ -153,7 +153,7 @@ util::Status JsonStreamParser::FinishParse() { // If we do not expect anything and there is nothing left to parse we're all // done. if (stack_.empty() && leftover_.empty()) { - return util::Status::OK; + return util::Status(); } // Storage for UTF8-coerced string. @@ -184,7 +184,7 @@ util::Status JsonStreamParser::FinishParse() { util::Status JsonStreamParser::ParseChunk(StringPiece chunk) { // Do not do any work if the chunk is empty. - if (chunk.empty()) return util::Status::OK; + if (chunk.empty()) return util::Status(); p_ = json_ = chunk; @@ -206,7 +206,7 @@ util::Status JsonStreamParser::ParseChunk(StringPiece chunk) { // unparsed data left, we save it for later parse. leftover_ = p_.ToString(); } - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::RunParser() { @@ -252,15 +252,15 @@ util::Status JsonStreamParser::RunParser() { // If we have a key we still need to render, make sure to save off the // contents in our own storage. if (!key_.empty() && key_storage_.empty()) { - key_.AppendToString(&key_storage_); + StrAppend(&key_storage_, key_); key_ = StringPiece(key_storage_); } - result = util::Status::OK; + result = util::Status(); } return result; } } - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseValue(TokenType type) { @@ -386,7 +386,7 @@ util::Status JsonStreamParser::ParseStringHelper() { // start fresh. string_open_ = 0; Advance(); - return util::Status::OK; + return util::Status(); } // Normal character, just advance past it. Advance(); @@ -468,7 +468,7 @@ util::Status JsonStreamParser::ParseUnicodeEscape() { // Advance past the [final] code unit escape. p_.remove_prefix(kUnicodeEscapedLength); parsed_storage_.append(buf, len); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseNumber() { @@ -542,7 +542,7 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { } result->type = NumberResult::DOUBLE; p_.remove_prefix(index); - return util::Status::OK; + return util::Status(); } // Positive non-floating point number, parse as a uint64. @@ -556,7 +556,7 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { } result->type = NumberResult::UINT; p_.remove_prefix(index); - return util::Status::OK; + return util::Status(); } // Octal/Hex numbers are not valid JSON values. @@ -569,7 +569,7 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { } result->type = NumberResult::INT; p_.remove_prefix(index); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::HandleBeginObject() { @@ -578,7 +578,7 @@ util::Status JsonStreamParser::HandleBeginObject() { ow_->StartObject(key_); key_ = StringPiece(); stack_.push(ENTRY); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseObjectMid(TokenType type) { @@ -590,13 +590,13 @@ util::Status JsonStreamParser::ParseObjectMid(TokenType type) { if (type == END_OBJECT) { Advance(); ow_->EndObject(); - return util::Status::OK; + return util::Status(); } // Found a comma, advance past it and get ready for an entry. if (type == VALUE_SEPARATOR) { Advance(); stack_.push(ENTRY); - return util::Status::OK; + return util::Status(); } // Illegal token after key:value pair. return ReportFailure("Expected , or } after key:value pair."); @@ -611,7 +611,7 @@ util::Status JsonStreamParser::ParseEntry(TokenType type) { if (type == END_OBJECT) { ow_->EndObject(); Advance(); - return util::Status::OK; + return util::Status(); } util::Status result; @@ -650,7 +650,7 @@ util::Status JsonStreamParser::ParseEntryMid(TokenType type) { if (type == ENTRY_SEPARATOR) { Advance(); stack_.push(VALUE); - return util::Status::OK; + return util::Status(); } return ReportFailure("Expected : between key:value pair."); } @@ -661,7 +661,7 @@ util::Status JsonStreamParser::HandleBeginArray() { ow_->StartList(key_); key_ = StringPiece(); stack_.push(ARRAY_VALUE); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseArrayValue(TokenType type) { @@ -672,7 +672,7 @@ util::Status JsonStreamParser::ParseArrayValue(TokenType type) { if (type == END_ARRAY) { ow_->EndList(); Advance(); - return util::Status::OK; + return util::Status(); } // The ParseValue call may push something onto the stack so we need to make @@ -696,14 +696,14 @@ util::Status JsonStreamParser::ParseArrayMid(TokenType type) { if (type == END_ARRAY) { ow_->EndList(); Advance(); - return util::Status::OK; + return util::Status(); } // Found a comma, advance past it and expect an array value next. if (type == VALUE_SEPARATOR) { Advance(); stack_.push(ARRAY_VALUE); - return util::Status::OK; + return util::Status(); } // Illegal token after array value. return ReportFailure("Expected , or ] after array value."); @@ -713,27 +713,27 @@ util::Status JsonStreamParser::ParseTrue() { ow_->RenderBool(key_, true); key_ = StringPiece(); p_.remove_prefix(true_len); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseFalse() { ow_->RenderBool(key_, false); key_ = StringPiece(); p_.remove_prefix(false_len); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseNull() { ow_->RenderNull(key_); key_ = StringPiece(); p_.remove_prefix(null_len); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseEmptyNull() { ow_->RenderNull(key_); key_ = StringPiece(); - return util::Status::OK; + return util::Status(); } bool JsonStreamParser::IsEmptyNullAllowed(TokenType type) { @@ -793,7 +793,7 @@ util::Status JsonStreamParser::ParseKey() { } // Since we aren't using the key storage, clear it out. key_storage_.clear(); - return util::Status::OK; + return util::Status(); } JsonStreamParser::TokenType JsonStreamParser::GetNextTokenType() { diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h index 21dff88d..0db8485c 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. - virtual ProtoWriter* StartObject(StringPiece name); - virtual ProtoWriter* EndObject(); - virtual ProtoWriter* StartList(StringPiece name); - virtual ProtoWriter* EndList(); - virtual ProtoWriter* RenderBool(StringPiece name, bool value) { + ProtoWriter* StartObject(StringPiece name); + ProtoWriter* EndObject(); + ProtoWriter* StartList(StringPiece name); + ProtoWriter* EndList(); + ProtoWriter* RenderBool(StringPiece name, bool value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderInt32(StringPiece name, int32 value) { + ProtoWriter* RenderInt32(StringPiece name, int32 value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderUint32(StringPiece name, uint32 value) { + ProtoWriter* RenderUint32(StringPiece name, uint32 value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderInt64(StringPiece name, int64 value) { + ProtoWriter* RenderInt64(StringPiece name, int64 value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderUint64(StringPiece name, uint64 value) { + ProtoWriter* RenderUint64(StringPiece name, uint64 value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderDouble(StringPiece name, double value) { + ProtoWriter* RenderDouble(StringPiece name, double value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderFloat(StringPiece name, float value) { + ProtoWriter* RenderFloat(StringPiece name, float value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderString(StringPiece name, StringPiece value) { + ProtoWriter* RenderString(StringPiece name, StringPiece value) { 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())); } - virtual ProtoWriter* RenderNull(StringPiece name) { + ProtoWriter* RenderNull(StringPiece name) { return RenderDataPiece(name, DataPiece::NullData()); } @@ -242,7 +242,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type, strings::ByteSink* output, ErrorListener* listener); - virtual ProtoElement* element() { return element_.get(); } + ProtoElement* element() { return element_.get(); } // Helper methods for calling ErrorListener. See error_listener.h. void InvalidName(StringPiece unknown_name, StringPiece message); diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 61491af0..025fbd40 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -240,7 +240,7 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, if (include_start_and_end) { ow->EndObject(); } - return Status::OK; + return util::Status(); } StatusOr<uint32> ProtoStreamObjectSource::RenderList( @@ -322,7 +322,7 @@ Status ProtoStreamObjectSource::RenderPacked( RETURN_IF_ERROR(RenderField(field, StringPiece(), ow)); } stream_->PopLimit(old_limit); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderTimestamp( @@ -346,7 +346,7 @@ Status ProtoStreamObjectSource::RenderTimestamp( ow->RenderString(field_name, ::google::protobuf::internal::FormatTime(seconds, nanos)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderDuration( @@ -387,7 +387,7 @@ Status ProtoStreamObjectSource::RenderDuration( FormatNanos(nanos, os->add_trailing_zeros_for_timestamp_and_duration_) .c_str()); ow->RenderString(field_name, formatted_duration); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os, @@ -401,7 +401,7 @@ Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderDouble(field_name, bit_cast<double>(buffer64)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os, @@ -415,7 +415,7 @@ Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderFloat(field_name, bit_cast<float>(buffer32)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os, @@ -429,7 +429,7 @@ Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderInt64(field_name, bit_cast<int64>(buffer64)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os, @@ -443,7 +443,7 @@ Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderUint64(field_name, bit_cast<uint64>(buffer64)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os, @@ -457,7 +457,7 @@ Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderInt32(field_name, bit_cast<int32>(buffer32)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os, @@ -471,7 +471,7 @@ Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderUint32(field_name, bit_cast<uint32>(buffer32)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os, @@ -486,7 +486,7 @@ Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderBool(field_name, buffer64 != 0); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os, @@ -502,7 +502,7 @@ Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderString(field_name, str); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os, @@ -518,7 +518,7 @@ Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderBytes(field_name, str); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, @@ -537,7 +537,7 @@ Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, } } ow->EndObject(); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderStructValue( @@ -553,7 +553,7 @@ Status ProtoStreamObjectSource::RenderStructValue( } RETURN_IF_ERROR(os->RenderField(field, field_name, ow)); } - return Status::OK; + return util::Status(); } // TODO(skarvaje): Avoid code duplication of for loops and SkipField logic. @@ -566,7 +566,7 @@ Status ProtoStreamObjectSource::RenderStructListValue( if (tag == 0) { ow->StartList(field_name); ow->EndList(); - return Status::OK; + return util::Status(); } while (tag != 0) { @@ -578,7 +578,7 @@ Status ProtoStreamObjectSource::RenderStructListValue( } ASSIGN_OR_RETURN(tag, os->RenderList(field, field_name, tag, ow)); } - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, @@ -620,7 +620,7 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, ow->RenderString("@type", type_url); } ow->EndObject(); - return util::Status::OK; + return util::Status(); } // If there is a value but no type, we cannot render it, so report an error. @@ -685,7 +685,7 @@ Status ProtoStreamObjectSource::RenderFieldMask( combined.append(ConvertFieldMaskPath(str, &ToCamelCase)); } ow->RenderString(field_name, combined); - return Status::OK; + return util::Status(); } @@ -781,7 +781,7 @@ Status ProtoStreamObjectSource::RenderField( // Render all other non-message types. return RenderNonMessageField(field, field_name, ow); } - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderNonMessageField( @@ -910,7 +910,7 @@ Status ProtoStreamObjectSource::RenderNonMessageField( default: break; } - return Status::OK; + return util::Status(); } // TODO(skarvaje): Fix this to avoid code duplication. @@ -1079,7 +1079,7 @@ Status ProtoStreamObjectSource::IncrementRecursionDepth( StrCat("Message too deep. Max recursion depth reached for type '", type_name, "', field '", field_name, "'")); } - return Status::OK; + return util::Status(); } namespace { diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index 5f443d9d..58d77c2c 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -112,9 +112,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // Sets whether to always output enums as ints, by default this is off, and // enums are rendered as strings. - void set_use_ints_for_enums(bool value) { - use_ints_for_enums_ = value; - } + void set_use_ints_for_enums(bool value) { use_ints_for_enums_ = value; } // Sets whether to use original proto field names void set_preserve_proto_field_names(bool value) { diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc index e215c4ab..06c9bb6d 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc @@ -111,7 +111,7 @@ class ProtostreamObjectSourceTest void DoTest(const Message& msg, const Descriptor* descriptor) { Status status = ExecuteTest(msg, descriptor); - EXPECT_EQ(Status::OK, status); + EXPECT_EQ(util::Status(), status); } Status ExecuteTest(const Message& msg, const Descriptor* descriptor) { @@ -509,9 +509,7 @@ TEST_P(ProtostreamObjectSourceTest, UseIntsForEnumsTest) { UseIntsForEnums(); - ow_.StartObject("") - ->RenderInt32("type", 3) - ->EndObject(); + ow_.StartObject("")->RenderInt32("type", 3)->EndObject(); DoTest(book, Book::descriptor()); } diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 6c9bc30e..d4e15bca 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -173,7 +173,7 @@ Status GetNanosFromStringPiece(StringPiece s_nanos, *nanos = i_nanos * conversion; } - return Status::OK; + return Status(); } } // namespace @@ -409,7 +409,7 @@ void ProtoStreamObjectWriter::AnyWriter::Event::DeepCopy() { // string value stays valid, we make a copy of the string value and update // DataPiece to reference our own copy. if (value_.type() == DataPiece::TYPE_STRING) { - value_.str().AppendToString(&value_storage_); + StrAppend(&value_storage_, value_.str()); value_ = DataPiece(value_storage_, value_.use_strict_base64_decoding()); } else if (value_.type() == DataPiece::TYPE_BYTES) { value_storage_ = value_.ToBytes().ValueOrDie(); @@ -862,7 +862,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, ow->ProtoWriter::RenderDataPiece( "string_value", DataPiece(SimpleItoa(int_value.ValueOrDie()), true)); - return Status::OK; + return Status(); } } struct_field_name = "number_value"; @@ -877,13 +877,22 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, ow->ProtoWriter::RenderDataPiece( "string_value", DataPiece(SimpleItoa(int_value.ValueOrDie()), true)); - return Status::OK; + return Status(); } } struct_field_name = "number_value"; break; } case DataPiece::TYPE_DOUBLE: { + if (ow->options_.struct_integers_as_strings) { + StatusOr<double> double_value = data.ToDouble(); + if (double_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", + DataPiece(SimpleDtoa(double_value.ValueOrDie()), true)); + return Status(); + } + } struct_field_name = "number_value"; break; } @@ -906,12 +915,12 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, } } ow->ProtoWriter::RenderDataPiece(struct_field_name, data); - return Status::OK; + return Status(); } Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, const DataPiece& data) { - if (data.type() == DataPiece::TYPE_NULL) return Status::OK; + if (data.type() == DataPiece::TYPE_NULL) return Status(); if (data.type() != DataPiece::TYPE_STRING) { return Status(INVALID_ARGUMENT, StrCat("Invalid data type for timestamp, value is ", @@ -930,19 +939,19 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds)); ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos)); - return Status::OK; + return Status(); } static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow, StringPiece path) { ow->ProtoWriter::RenderDataPiece( "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true)); - return Status::OK; + return Status(); } Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow, const DataPiece& data) { - if (data.type() == DataPiece::TYPE_NULL) return Status::OK; + if (data.type() == DataPiece::TYPE_NULL) return Status(); if (data.type() != DataPiece::TYPE_STRING) { return Status(INVALID_ARGUMENT, StrCat("Invalid data type for field mask, value is ", @@ -959,7 +968,7 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow, Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow, const DataPiece& data) { - if (data.type() == DataPiece::TYPE_NULL) return Status::OK; + if (data.type() == DataPiece::TYPE_NULL) return Status(); if (data.type() != DataPiece::TYPE_STRING) { return Status(INVALID_ARGUMENT, StrCat("Invalid data type for duration, value is ", @@ -1004,14 +1013,14 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow, ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds)); ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos)); - return Status::OK; + return Status(); } Status ProtoStreamObjectWriter::RenderWrapperType(ProtoStreamObjectWriter* ow, const DataPiece& data) { - if (data.type() == DataPiece::TYPE_NULL) return Status::OK; + if (data.type() == DataPiece::TYPE_NULL) return Status(); ow->ProtoWriter::RenderDataPiece("value", data); - return Status::OK; + return Status(); } ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h index 732971e1..ab534912 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.h +++ b/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -76,11 +76,14 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { public: // Options that control ProtoStreamObjectWriter class's behavior. struct Options { - // Treats integer inputs in google.protobuf.Struct as strings. Normally, - // integer values are returned in double field "number_value" of + // Treats numeric inputs in google.protobuf.Struct as strings. Normally, + // numeric values are returned in double field "number_value" of // google.protobuf.Struct. However, this can cause precision loss for - // int64/uint64 inputs. This option is provided for cases that want to - // preserve integer precision. + // int64/uint64/double inputs. This option is provided for cases that want + // to preserve number precision. + // + // TODO(skarvaje): Rename to struct_numbers_as_strings as it covers double + // as well. bool struct_integers_as_strings; // Not treat unknown fields as an error. If there is an unknown fields, diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index 97ef8fff..87d35b08 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -279,17 +279,13 @@ TEST_P(ProtoStreamObjectWriterTest, ConflictingJsonName) { ResetTypeInfo(TestJsonName1::descriptor()); TestJsonName1 message1; message1.set_one_value(12345); - ow_->StartObject("") - ->RenderInt32("value", 12345) - ->EndObject(); + ow_->StartObject("")->RenderInt32("value", 12345)->EndObject(); CheckOutput(message1); ResetTypeInfo(TestJsonName2::descriptor()); TestJsonName2 message2; message2.set_another_value(12345); - ow_->StartObject("") - ->RenderInt32("value", 12345) - ->EndObject(); + ow_->StartObject("")->RenderInt32("value", 12345)->EndObject(); CheckOutput(message2); } @@ -1615,7 +1611,7 @@ TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapObjectKeyTest) { TEST_P(ProtoStreamObjectWriterStructTest, OptionStructIntAsStringsTest) { StructType struct_type; google::protobuf::Struct* s = struct_type.mutable_object(); - s->mutable_fields()->operator[]("k1").set_number_value(123); + s->mutable_fields()->operator[]("k1").set_string_value("123"); s->mutable_fields()->operator[]("k2").set_bool_value(true); s->mutable_fields()->operator[]("k3").set_string_value("-222222222"); s->mutable_fields()->operator[]("k4").set_string_value("33333333"); diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index a5d903f1..85d0d5c9 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -107,10 +107,12 @@ class TypeInfoForTypeResolver : public TypeInfo { virtual const google::protobuf::Field* FindField( const google::protobuf::Type* type, StringPiece camel_case_name) const { - std::map<const google::protobuf::Type*, - CamelCaseNameTable>::const_iterator it = indexed_types_.find(type); - const CamelCaseNameTable& camel_case_name_table = (it == indexed_types_.end()) - ? PopulateNameLookupTable(type, &indexed_types_[type]) : it->second; + std::map<const google::protobuf::Type*, CamelCaseNameTable>::const_iterator + it = indexed_types_.find(type); + const CamelCaseNameTable& camel_case_name_table = + (it == indexed_types_.end()) + ? PopulateNameLookupTable(type, &indexed_types_[type]) + : it->second; StringPiece name = FindWithDefault(camel_case_name_table, camel_case_name, StringPiece()); if (name.empty()) { @@ -142,8 +144,8 @@ class TypeInfoForTypeResolver : public TypeInfo { const google::protobuf::Field& field = type->fields(i); StringPiece name = field.name(); StringPiece camel_case_name = field.json_name(); - const StringPiece* existing = InsertOrReturnExisting( - camel_case_name_table, camel_case_name, name); + const StringPiece* existing = + InsertOrReturnExisting(camel_case_name_table, camel_case_name, name); if (existing && *existing != name) { GOOGLE_LOG(WARNING) << "Field '" << name << "' and '" << *existing << "' map to the same camel case name '" << camel_case_name @@ -162,8 +164,8 @@ class TypeInfoForTypeResolver : public TypeInfo { mutable std::map<StringPiece, StatusOrType> cached_types_; mutable std::map<StringPiece, StatusOrEnum> cached_enums_; - mutable std::map<const google::protobuf::Type*, - CamelCaseNameTable> indexed_types_; + mutable std::map<const google::protobuf::Type*, CamelCaseNameTable> + indexed_types_; }; } // namespace diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index 6daf24eb..8cf42e49 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -48,16 +48,6 @@ namespace protobuf { namespace util { namespace converter { -namespace { -const StringPiece SkipWhiteSpace(StringPiece str) { - StringPiece::size_type i; - for (i = 0; i < str.size() && isspace(str[i]); ++i) { - } - GOOGLE_DCHECK(i == str.size() || !isspace(str[i])); - return str.substr(i); -} -} // namespace - bool GetBoolOptionOrDefault( const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options, const string& option_name, bool default_value) { diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc index 8595a881..c85f1899 100644 --- a/src/google/protobuf/util/json_util.cc +++ b/src/google/protobuf/util/json_util.cc @@ -84,7 +84,7 @@ util::Status BinaryToJsonStream(TypeResolver* resolver, converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type); proto_source.set_use_ints_for_enums(options.always_print_enums_as_ints); proto_source.set_preserve_proto_field_names( - options.preserve_proto_field_names); + options.preserve_proto_field_names); io::CodedOutputStream out_stream(json_output); converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "", &out_stream); @@ -92,7 +92,7 @@ util::Status BinaryToJsonStream(TypeResolver* resolver, converter::DefaultValueObjectWriter default_value_writer( resolver, type, &json_writer); default_value_writer.set_preserve_proto_field_names( - options.preserve_proto_field_names); + options.preserve_proto_field_names); return proto_source.WriteTo(&default_value_writer); } else { return proto_source.WriteTo(&json_writer); @@ -113,7 +113,7 @@ util::Status BinaryToJsonString(TypeResolver* resolver, namespace { class StatusErrorListener : public converter::ErrorListener { public: - StatusErrorListener() : status_(util::Status::OK) {} + StatusErrorListener() {} virtual ~StatusErrorListener() {} util::Status GetStatus() { return status_; } diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h index dd9a736f..f4f4380a 100644 --- a/src/google/protobuf/util/json_util.h +++ b/src/google/protobuf/util/json_util.h @@ -67,11 +67,11 @@ struct JsonPrintOptions { // Whether to preserve proto field names bool preserve_proto_field_names; - JsonPrintOptions() : add_whitespace(false), - always_print_primitive_fields(false), - always_print_enums_as_ints(false), - preserve_proto_field_names(false) { - } + JsonPrintOptions() + : add_whitespace(false), + always_print_primitive_fields(false), + always_print_enums_as_ints(false), + preserve_proto_field_names(false) {} }; // DEPRECATED. Use JsonPrintOptions instead. diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc index 7c03d674..25c7e96c 100644 --- a/src/google/protobuf/util/json_util_test.cc +++ b/src/google/protobuf/util/json_util_test.cc @@ -52,14 +52,10 @@ using proto3::BAR; using proto3::TestMessage; using proto3::TestMap; using proto3::TestOneof; -using testing::MapIn; +using google::protobuf::testing::MapIn; static const char kTypeUrlPrefix[] = "type.googleapis.com"; -static string GetTypeUrl(const Descriptor* message) { - return string(kTypeUrlPrefix) + "/" + message->full_name(); -} - // As functions defined in json_util.h are just thin wrappers around the // JSON conversion code in //net/proto2/util/converter, in this test we // only cover some very basic cases to make sure the wrappers have forwarded @@ -207,8 +203,7 @@ TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) { JsonPrintOptions print_options; print_options.always_print_enums_as_ints = true; - string expected_json = - "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}"; + string expected_json = "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}"; EXPECT_EQ(expected_json, ToJson(orig, print_options)); TestMessage parsed; @@ -264,7 +259,8 @@ TEST_F(JsonUtilTest, ParsePrimitiveMapIn) { JsonPrintOptions print_options; print_options.always_print_primitive_fields = true; JsonParseOptions parse_options; - EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}", ToJson(message, print_options)); + EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}", + ToJson(message, print_options)); MapIn other; ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options)); EXPECT_EQ(message.DebugString(), other.DebugString()); @@ -275,14 +271,10 @@ TEST_F(JsonUtilTest, PrintPrimitiveOneof) { JsonPrintOptions options; options.always_print_primitive_fields = true; message.mutable_oneof_message_value(); - EXPECT_EQ( - "{\"oneofMessageValue\":{\"value\":0}}", - ToJson(message, options)); + EXPECT_EQ("{\"oneofMessageValue\":{\"value\":0}}", ToJson(message, options)); message.set_oneof_int32_value(1); - EXPECT_EQ( - "{\"oneofInt32Value\":1}", - ToJson(message, options)); + EXPECT_EQ("{\"oneofInt32Value\":1}", ToJson(message, options)); } TEST_F(JsonUtilTest, TestParseIgnoreUnknownFields) { diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 203d8388..830850be 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -467,6 +467,10 @@ bool MessageDifferencer::Compare( google::protobuf::scoped_ptr<Message> data1; google::protobuf::scoped_ptr<Message> data2; if (UnpackAny(message1, &data1) && UnpackAny(message2, &data2)) { + // Avoid DFATAL for different descriptors in google.protobuf.Any payloads. + if (data1->GetDescriptor() != data2->GetDescriptor()) { + return false; + } return Compare(*data1, *data2, parent_fields); } } @@ -849,7 +853,8 @@ bool MessageDifferencer::CompareRepeatedField( parent_fields->pop_back(); fieldDifferent = true; } else if (reporter_ != NULL && - specific_field.index != specific_field.new_index) { + specific_field.index != specific_field.new_index && + !specific_field.field->is_map()) { parent_fields->push_back(specific_field); reporter_->ReportMoved(message1, message2, *parent_fields); parent_fields->pop_back(); @@ -1503,6 +1508,10 @@ void MessageDifferencer::StreamReporter::PrintPath( } else { printer_->PrintRaw(specific_field.field->name()); } + if (specific_field.field->is_map()) { + // Don't print index in a map field; they are semantically unordered. + continue; + } } else { printer_->PrintRaw(SimpleItoa(specific_field.unknown_field_number)); } diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc index 30b27dba..850b3977 100755 --- a/src/google/protobuf/util/message_differencer_unittest.cc +++ b/src/google/protobuf/util/message_differencer_unittest.cc @@ -38,6 +38,7 @@ #include <string> #include <vector> +#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/util/field_comparator.h> #include <google/protobuf/util/message_differencer.h> @@ -54,7 +55,6 @@ #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/strutil.h> #include <google/protobuf/testing/googletest.h> #include <gtest/gtest.h> @@ -2042,6 +2042,9 @@ class ComparisonTest : public testing::Test { unittest::TestEmptyMessage empty1_; unittest::TestEmptyMessage empty2_; + unittest::TestMap map_proto1_; + unittest::TestMap map_proto2_; + UnknownFieldSet* unknown1_; UnknownFieldSet* unknown2_; @@ -2802,6 +2805,24 @@ TEST_F(ComparisonTest, EquivalentIgnoresUnknown) { EXPECT_TRUE(util::MessageDifferencer::Equivalent(message1, message2)); } +TEST_F(ComparisonTest, MapTest) { + repeated_field_as_set(); + + Map<string, string>& map1 = *map_proto1_.mutable_map_string_string(); + map1["1"] = "1"; + map1["2"] = "2"; + map1["3"] = "3"; + Map<string, string>& map2 = *map_proto2_.mutable_map_string_string(); + map2["3"] = "0"; + map2["2"] = "2"; + map2["1"] = "1"; + + EXPECT_EQ( + "added: map_string_string: { key: \"3\" value: \"0\" }\n" + "deleted: map_string_string: { key: \"3\" value: \"3\" }\n", + Run(map_proto1_, map_proto2_)); +} + class MatchingTest : public testing::Test { public: typedef util::MessageDifferencer MessageDifferencer; @@ -3146,6 +3167,24 @@ TEST(Anytest, TreatAsSet) { EXPECT_TRUE(message_differencer.Compare(m1, m2)); } +TEST(Anytest, TreatAsSet_DifferentType) { + protobuf_unittest::TestField value1; + value1.set_a(20); + value1.set_b(30); + protobuf_unittest::TestDiffMessage value2; + value2.add_rv(40); + + protobuf_unittest::TestAny m1, m2; + m1.add_repeated_any_value()->PackFrom(value1); + m1.add_repeated_any_value()->PackFrom(value2); + m2.add_repeated_any_value()->PackFrom(value2); + m2.add_repeated_any_value()->PackFrom(value1); + + util::MessageDifferencer message_differencer; + message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value")); + EXPECT_TRUE(message_differencer.Compare(m1, m2)); +} + } // namespace } // namespace protobuf diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc index b11f822a..46a6f5a8 100644 --- a/src/google/protobuf/util/time_util.cc +++ b/src/google/protobuf/util/time_util.cc @@ -49,11 +49,9 @@ static const int kNanosPerSecond = 1000000000; static const int kMicrosPerSecond = 1000000; static const int kMillisPerSecond = 1000; static const int kNanosPerMillisecond = 1000000; -static const int kMicrosPerMillisecond = 1000; static const int kNanosPerMicrosecond = 1000; static const int kSecondsPerMinute = 60; // Note that we ignore leap seconds. static const int kSecondsPerHour = 3600; -static const char kTimestampFormat[] = "%E4Y-%m-%dT%H:%M:%S"; template <typename T> T CreateNormalized(int64 seconds, int64 nanos); @@ -376,19 +374,6 @@ namespace { using google::protobuf::util::kNanosPerSecond; using google::protobuf::util::CreateNormalized; -// Convert a Timestamp to uint128. -void ToUint128(const Timestamp& value, uint128* result, bool* negative) { - if (value.seconds() < 0) { - *negative = true; - *result = static_cast<uint64>(-value.seconds()); - *result = *result * kNanosPerSecond - static_cast<uint32>(value.nanos()); - } else { - *negative = false; - *result = static_cast<uint64>(value.seconds()); - *result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos()); - } -} - // Convert a Duration to uint128. void ToUint128(const Duration& value, uint128* result, bool* negative) { if (value.seconds() < 0 || value.nanos() < 0) { @@ -402,21 +387,6 @@ void ToUint128(const Duration& value, uint128* result, bool* negative) { } } -void ToTimestamp(const uint128& value, bool negative, Timestamp* timestamp) { - int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond)); - int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond)); - if (negative) { - seconds = -seconds; - nanos = -nanos; - if (nanos < 0) { - nanos += kNanosPerSecond; - seconds -= 1; - } - } - timestamp->set_seconds(seconds); - timestamp->set_nanos(nanos); -} - void ToDuration(const uint128& value, bool negative, Duration* duration) { int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond)); int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond)); |