1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #ifndef avro_Node_hh__
20 #define avro_Node_hh__
21
22 #include "Config.hh"
23
24 #include <cassert>
25 #include <boost/noncopyable.hpp>
26 #include <boost/shared_ptr.hpp>
27
28 #include "Exception.hh"
29 #include "Types.hh"
30 #include "SchemaResolution.hh"
31
32 namespace internal_avro {
33
34 class Node;
35
36 typedef boost::shared_ptr<Node> NodePtr;
37
38 class AVRO_DECL Name {
39 std::string ns_;
40 std::string simpleName_;
41
42 public:
Name()43 Name() {}
44 Name(const std::string& fullname);
Name(const std::string & simpleName,const std::string & ns)45 Name(const std::string& simpleName, const std::string& ns)
46 : ns_(ns), simpleName_(simpleName) {
47 check();
48 }
49
50 const std::string fullname() const;
ns() const51 const std::string& ns() const { return ns_; }
simpleName() const52 const std::string& simpleName() const { return simpleName_; }
53
ns(const std::string & n)54 void ns(const std::string& n) { ns_ = n; }
simpleName(const std::string & n)55 void simpleName(const std::string& n) { simpleName_ = n; }
56 void fullname(const std::string& n);
57
58 bool operator<(const Name& n) const;
59 void check() const;
60 bool operator==(const Name& n) const;
operator !=(const Name & n) const61 bool operator!=(const Name& n) const { return !((*this) == n); }
clear()62 void clear() {
63 ns_.clear();
64 simpleName_.clear();
65 }
operator std::string() const66 operator std::string() const { return fullname(); }
67 };
68
operator <<(std::ostream & os,const Name & n)69 inline std::ostream& operator<<(std::ostream& os, const Name& n) {
70 return os << n.fullname();
71 }
72
73 /// Node is the building block for parse trees. Each node represents an avro
74 /// type. Compound types have leaf nodes that represent the types they are
75 /// composed of.
76 ///
77 /// The user does not use the Node object directly, they interface with Schema
78 /// objects.
79 ///
80 /// The Node object uses reference-counted pointers. This is so that schemas
81 /// may be reused in other other schemas, without needing to worry about memory
82 /// deallocation for nodes that are added to multiple schema parse trees.
83 ///
84 /// Node has minimal implementation, serving as an abstract base class for
85 /// different node types.
86 ///
87
88 class AVRO_DECL Node : private boost::noncopyable {
89 public:
Node(Type type)90 Node(Type type) : type_(type), locked_(false) {}
91
92 virtual ~Node();
93
type() const94 Type type() const { return type_; }
95
lock()96 void lock() { locked_ = true; }
97
locked() const98 bool locked() const { return locked_; }
99
100 virtual bool hasName() const = 0;
101
setName(const Name & name)102 void setName(const Name& name) {
103 checkLock();
104 checkName(name);
105 doSetName(name);
106 }
107 virtual const Name& name() const = 0;
108
addLeaf(const NodePtr & newLeaf)109 void addLeaf(const NodePtr& newLeaf) {
110 checkLock();
111 doAddLeaf(newLeaf);
112 }
113 virtual size_t leaves() const = 0;
114 virtual const NodePtr& leafAt(int index) const = 0;
115
addName(const std::string & name)116 void addName(const std::string& name) {
117 checkLock();
118 checkName(name);
119 doAddName(name);
120 }
121 virtual size_t names() const = 0;
122 virtual const std::string& nameAt(int index) const = 0;
123 virtual bool nameIndex(const std::string& name, size_t& index) const = 0;
124
setFixedSize(int size)125 void setFixedSize(int size) {
126 checkLock();
127 doSetFixedSize(size);
128 }
129 virtual int fixedSize() const = 0;
130
131 virtual bool isValid() const = 0;
132
133 virtual SchemaResolution resolve(const Node& reader) const = 0;
134
135 virtual void printJson(std::ostream& os, int depth) const = 0;
136
137 virtual void printBasicInfo(std::ostream& os) const = 0;
138
139 virtual void setLeafToSymbolic(int index, const NodePtr& node) = 0;
140
141 protected:
checkLock() const142 void checkLock() const {
143 if (locked()) {
144 throw Exception("Cannot modify locked schema");
145 }
146 }
147
checkName(const Name & name) const148 virtual void checkName(const Name& name) const { name.check(); }
149
150 virtual void doSetName(const Name& name) = 0;
151 virtual void doAddLeaf(const NodePtr& newLeaf) = 0;
152 virtual void doAddName(const std::string& name) = 0;
153 virtual void doSetFixedSize(int size) = 0;
154
155 private:
156 const Type type_;
157 bool locked_;
158 };
159
160 } // namespace internal_avro
161
162 namespace std {
operator <<(std::ostream & os,const internal_avro::Node & n)163 inline std::ostream& operator<<(std::ostream& os,
164 const internal_avro::Node& n) {
165 n.printJson(os, 0);
166 return os;
167 }
168 }
169
170 #endif
171