summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/thrift/compiler/cpp/src/thrift/parse/t_struct.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/thrift/compiler/cpp/src/thrift/parse/t_struct.h')
-rw-r--r--src/jaegertracing/thrift/compiler/cpp/src/thrift/parse/t_struct.h165
1 files changed, 165 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/compiler/cpp/src/thrift/parse/t_struct.h b/src/jaegertracing/thrift/compiler/cpp/src/thrift/parse/t_struct.h
new file mode 100644
index 000000000..7e1e6caf0
--- /dev/null
+++ b/src/jaegertracing/thrift/compiler/cpp/src/thrift/parse/t_struct.h
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef T_STRUCT_H
+#define T_STRUCT_H
+
+#include <algorithm>
+#include <vector>
+#include <utility>
+#include <string>
+
+#include "thrift/parse/t_type.h"
+#include "thrift/parse/t_field.h"
+
+// Forward declare that puppy
+class t_program;
+
+/**
+ * A struct is a container for a set of member fields that has a name. Structs
+ * are also used to implement exception types.
+ *
+ */
+class t_struct : public t_type {
+public:
+ typedef std::vector<t_field*> members_type;
+
+ t_struct(t_program* program)
+ : t_type(program),
+ is_xception_(false),
+ is_union_(false),
+ members_validated(false),
+ members_with_value(0),
+ xsd_all_(false) {}
+
+ t_struct(t_program* program, const std::string& name)
+ : t_type(program, name),
+ is_xception_(false),
+ is_union_(false),
+ members_validated(false),
+ members_with_value(0),
+ xsd_all_(false) {}
+
+ void set_name(const std::string& name) override {
+ name_ = name;
+ validate_union_members();
+ }
+
+ void set_xception(bool is_xception) { is_xception_ = is_xception; }
+
+ void validate_union_member(t_field* field) {
+ if (is_union_ && (!name_.empty())) {
+
+ // 1) unions can't have required fields
+ // 2) union members are implicitly optional, otherwise bugs like THRIFT-3650 wait to happen
+ if (field->get_req() != t_field::T_OPTIONAL) {
+ // no warning on default requiredness, but do warn on anything else that is explicitly asked for
+ if(field->get_req() != t_field::T_OPT_IN_REQ_OUT) {
+ pwarning(1,
+ "Union %s field %s: union members must be optional, ignoring specified requiredness.\n",
+ name_.c_str(),
+ field->get_name().c_str());
+ }
+ field->set_req(t_field::T_OPTIONAL);
+ }
+
+ // unions may have up to one member defaulted, but not more
+ if (field->get_value() != nullptr) {
+ if (1 < ++members_with_value) {
+ throw "Error: Field " + field->get_name() + " provides another default value for union "
+ + name_;
+ }
+ }
+ }
+ }
+
+ void validate_union_members() {
+ if (is_union_ && (!name_.empty()) && (!members_validated)) {
+ members_type::const_iterator m_iter;
+ for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
+ validate_union_member(*m_iter);
+ }
+ members_validated = true;
+ }
+ }
+
+ void set_union(bool is_union) {
+ is_union_ = is_union;
+ validate_union_members();
+ }
+
+ void set_xsd_all(bool xsd_all) { xsd_all_ = xsd_all; }
+
+ bool get_xsd_all() const { return xsd_all_; }
+
+ bool append(t_field* elem) {
+ typedef members_type::iterator iter_type;
+ std::pair<iter_type, iter_type> bounds = std::equal_range(members_in_id_order_.begin(),
+ members_in_id_order_.end(),
+ elem,
+ t_field::key_compare());
+ if (bounds.first != bounds.second) {
+ return false;
+ }
+ // returns false when there is a conflict of field names
+ if (get_field_by_name(elem->get_name()) != nullptr) {
+ return false;
+ }
+ members_.push_back(elem);
+ members_in_id_order_.insert(bounds.second, elem);
+ validate_union_member(elem);
+ return true;
+ }
+
+ const members_type& get_members() const { return members_; }
+
+ const members_type& get_sorted_members() const { return members_in_id_order_; }
+
+ bool is_struct() const override { return !is_xception_; }
+
+ bool is_xception() const override { return is_xception_; }
+
+ bool is_union() const { return is_union_; }
+
+ t_field* get_field_by_name(std::string field_name) {
+ return const_cast<t_field*>(const_cast<const t_struct&>(*this).get_field_by_name(field_name));
+ }
+
+ const t_field* get_field_by_name(std::string field_name) const {
+ members_type::const_iterator m_iter;
+ for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
+ if ((*m_iter)->get_name() == field_name) {
+ return *m_iter;
+ }
+ }
+ return nullptr;
+ }
+
+private:
+ members_type members_;
+ members_type members_in_id_order_;
+ bool is_xception_;
+ bool is_union_;
+ bool members_validated;
+ int members_with_value;
+
+ bool xsd_all_;
+};
+
+#endif