blob: 695b9dd8a162b2544dbba1048a2aa7140dbce2a4 [file] [log] [blame]
Feng Xiaoe96ff302015-06-15 18:21:48 -07001// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#ifndef GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__
32#define GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__
33
34#include <memory>
35#ifndef _SHARED_PTR_H
36#include <google/protobuf/stubs/shared_ptr.h>
37#endif
38#include <stack>
39#include <vector>
40
41#include <google/protobuf/stubs/common.h>
42#include <google/protobuf/util/internal/type_info.h>
43#include <google/protobuf/util/internal/datapiece.h>
44#include <google/protobuf/util/internal/object_writer.h>
45#include <google/protobuf/util/internal/utility.h>
46#include <google/protobuf/util/type_resolver.h>
47#include <google/protobuf/stubs/stringpiece.h>
48
49namespace google {
50namespace protobuf {
51namespace util {
52namespace converter {
53
54// An ObjectWriter that renders non-repeated primitive fields of proto messages
55// with their default values. DefaultValueObjectWriter holds objects, lists and
56// fields it receives in a tree structure and writes them out to another
57// ObjectWriter when EndObject() is called on the root object. It also writes
58// out all non-repeated primitive fields that haven't been explicitly rendered
59// with their default values (0 for numbers, "" for strings, etc).
Bo Yangff7bdad2015-08-23 10:45:14 -070060class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
Feng Xiaoe96ff302015-06-15 18:21:48 -070061 public:
62 DefaultValueObjectWriter(TypeResolver* type_resolver,
63 const google::protobuf::Type& type,
64 ObjectWriter* ow);
65
66 virtual ~DefaultValueObjectWriter();
67
68 // ObjectWriter methods.
69 virtual DefaultValueObjectWriter* StartObject(StringPiece name);
70
71 virtual DefaultValueObjectWriter* EndObject();
72
73 virtual DefaultValueObjectWriter* StartList(StringPiece name);
74
75 virtual DefaultValueObjectWriter* EndList();
76
77 virtual DefaultValueObjectWriter* RenderBool(StringPiece name, bool value);
78
79 virtual DefaultValueObjectWriter* RenderInt32(StringPiece name, int32 value);
80
81 virtual DefaultValueObjectWriter* RenderUint32(StringPiece name,
82 uint32 value);
83
84 virtual DefaultValueObjectWriter* RenderInt64(StringPiece name, int64 value);
85
86 virtual DefaultValueObjectWriter* RenderUint64(StringPiece name,
87 uint64 value);
88
89 virtual DefaultValueObjectWriter* RenderDouble(StringPiece name,
90 double value);
91
92 virtual DefaultValueObjectWriter* RenderFloat(StringPiece name, float value);
93
94 virtual DefaultValueObjectWriter* RenderString(StringPiece name,
95 StringPiece value);
96 virtual DefaultValueObjectWriter* RenderBytes(StringPiece name,
97 StringPiece value);
98
99 virtual DefaultValueObjectWriter* RenderNull(StringPiece name);
100
Feng Xiaoe96ff302015-06-15 18:21:48 -0700101 private:
102 enum NodeKind {
103 PRIMITIVE = 0,
104 OBJECT = 1,
105 LIST = 2,
106 MAP = 3,
107 };
108
109 // "Node" represents a node in the tree that holds the input of
110 // DefaultValueObjectWriter.
Jisi Liu46e8ff62015-10-05 11:59:43 -0700111 class LIBPROTOBUF_EXPORT Node {
Feng Xiaoe96ff302015-06-15 18:21:48 -0700112 public:
113 Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
114 const DataPiece& data, bool is_placeholder);
115 virtual ~Node() {
116 for (int i = 0; i < children_.size(); ++i) {
117 delete children_[i];
118 }
119 }
120
121 // Adds a child to this node. Takes ownership of this child.
122 void AddChild(Node* child) { children_.push_back(child); }
123
124 // Finds the child given its name.
125 Node* FindChild(StringPiece name);
126
127 // Populates children of this Node based on its type. If there are already
128 // children created, they will be merged to the result. Caller should pass
129 // in TypeInfo for looking up types of the children.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700130 void PopulateChildren(const TypeInfo* typeinfo);
Feng Xiaoe96ff302015-06-15 18:21:48 -0700131
132 // If this node is a leaf (has data), writes the current node to the
133 // ObjectWriter; if not, then recursively writes the children to the
134 // ObjectWriter.
135 void WriteTo(ObjectWriter* ow);
136
137 // Accessors
138 const string& name() const { return name_; }
139
140 const google::protobuf::Type* type() { return type_; }
141
142 void set_type(const google::protobuf::Type* type) { type_ = type; }
143
144 NodeKind kind() { return kind_; }
145
146 int number_of_children() { return children_.size(); }
147
148 void set_data(const DataPiece& data) { data_ = data; }
149
Feng Xiaoe96ff302015-06-15 18:21:48 -0700150 bool is_any() { return is_any_; }
151
152 void set_is_any(bool is_any) { is_any_ = is_any; }
153
154 void set_is_placeholder(bool is_placeholder) {
155 is_placeholder_ = is_placeholder;
156 }
157
158 private:
159 // Returns the Value Type of a map given the Type of the map entry and a
160 // TypeInfo instance.
161 const google::protobuf::Type* GetMapValueType(
Feng Xiaoeee38b02015-08-22 18:25:48 -0700162 const google::protobuf::Type& entry_type, const TypeInfo* typeinfo);
163
164 // Calls WriteTo() on every child in children_.
165 void WriteChildren(ObjectWriter* ow);
Feng Xiaoe96ff302015-06-15 18:21:48 -0700166
167 // The name of this node.
168 string name_;
169 // google::protobuf::Type of this node. Owned by TypeInfo.
170 const google::protobuf::Type* type_;
171 // The kind of this node.
172 NodeKind kind_;
Feng Xiaoe96ff302015-06-15 18:21:48 -0700173 // Whether this is a node for "Any".
174 bool is_any_;
175 // The data of this node when it is a leaf node.
176 DataPiece data_;
177 // Children of this node.
178 std::vector<Node*> children_;
179 // Whether this node is a placeholder for an object or list automatically
180 // generated when creating the parent node. Should be set to false after
181 // the parent node's StartObject()/StartList() method is called with this
182 // node's name.
183 bool is_placeholder_;
184 };
185
186 // Populates children of "node" if it is an "any" Node and its real type has
187 // been given.
188 void MaybePopulateChildrenOfAny(Node* node);
189
190 // Writes the root_ node to ow_ and resets the root_ and current_ pointer to
191 // NULL.
192 void WriteRoot();
193
194 // Creates a DataPiece containing the default value of the type of the field.
195 static DataPiece CreateDefaultDataPieceForField(
Feng Xiaoe841bac2015-12-11 17:09:20 -0800196 const google::protobuf::Field& field, const TypeInfo* typeinfo);
Feng Xiaoe96ff302015-06-15 18:21:48 -0700197
198 // Adds or replaces the data_ of a primitive child node.
199 void RenderDataPiece(StringPiece name, const DataPiece& data);
200
Feng Xiaoe841bac2015-12-11 17:09:20 -0800201 // Returns the default enum value as a DataPiece, or the first enum value if
202 // there is no default. For proto3, where we cannot specify an explicit
203 // default, a zero value will always be returned.
204 static DataPiece FindEnumDefault(const google::protobuf::Field& field,
205 const TypeInfo* typeinfo);
206
Feng Xiaoe96ff302015-06-15 18:21:48 -0700207 // Type information for all the types used in the descriptor. Used to find
208 // google::protobuf::Type of nested messages/enums.
Feng Xiaoeee38b02015-08-22 18:25:48 -0700209 const TypeInfo* typeinfo_;
210 // Whether the TypeInfo object is owned by this class.
211 bool own_typeinfo_;
Feng Xiaoe96ff302015-06-15 18:21:48 -0700212 // google::protobuf::Type of the root message type.
213 const google::protobuf::Type& type_;
214 // Holds copies of strings passed to RenderString.
215 vector<string*> string_values_;
216
Feng Xiaoe96ff302015-06-15 18:21:48 -0700217 // The current Node. Owned by its parents.
218 Node* current_;
219 // The root Node.
220 google::protobuf::scoped_ptr<Node> root_;
221 // The stack to hold the path of Nodes from current_ to root_;
222 std::stack<Node*> stack_;
223
224 ObjectWriter* ow_;
225
226 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DefaultValueObjectWriter);
227};
228
229} // namespace converter
230} // namespace util
231} // namespace protobuf
232
233} // namespace google
234#endif // GOOGLE_PROTOBUF_UTIL_CONVERTER_DEFAULT_VALUE_OBJECTWRITER_H__