]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/compiler/cpp/src/thrift/parse/t_struct.h
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / jaegertracing / thrift / compiler / cpp / src / thrift / parse / t_struct.h
CommitLineData
f67539c2
TL
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,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20#ifndef T_STRUCT_H
21#define T_STRUCT_H
22
23#include <algorithm>
24#include <vector>
25#include <utility>
26#include <string>
27
28#include "thrift/parse/t_type.h"
29#include "thrift/parse/t_field.h"
30
31// Forward declare that puppy
32class t_program;
33
34/**
35 * A struct is a container for a set of member fields that has a name. Structs
36 * are also used to implement exception types.
37 *
38 */
39class t_struct : public t_type {
40public:
41 typedef std::vector<t_field*> members_type;
42
43 t_struct(t_program* program)
44 : t_type(program),
45 is_xception_(false),
46 is_union_(false),
47 members_validated(false),
48 members_with_value(0),
49 xsd_all_(false) {}
50
51 t_struct(t_program* program, const std::string& name)
52 : t_type(program, name),
53 is_xception_(false),
54 is_union_(false),
55 members_validated(false),
56 members_with_value(0),
57 xsd_all_(false) {}
58
59 void set_name(const std::string& name) override {
60 name_ = name;
61 validate_union_members();
62 }
63
64 void set_xception(bool is_xception) { is_xception_ = is_xception; }
65
66 void validate_union_member(t_field* field) {
67 if (is_union_ && (!name_.empty())) {
68
69 // 1) unions can't have required fields
70 // 2) union members are implicitly optional, otherwise bugs like THRIFT-3650 wait to happen
71 if (field->get_req() != t_field::T_OPTIONAL) {
72 // no warning on default requiredness, but do warn on anything else that is explicitly asked for
73 if(field->get_req() != t_field::T_OPT_IN_REQ_OUT) {
74 pwarning(1,
75 "Union %s field %s: union members must be optional, ignoring specified requiredness.\n",
76 name_.c_str(),
77 field->get_name().c_str());
78 }
79 field->set_req(t_field::T_OPTIONAL);
80 }
81
82 // unions may have up to one member defaulted, but not more
83 if (field->get_value() != nullptr) {
84 if (1 < ++members_with_value) {
85 throw "Error: Field " + field->get_name() + " provides another default value for union "
86 + name_;
87 }
88 }
89 }
90 }
91
92 void validate_union_members() {
93 if (is_union_ && (!name_.empty()) && (!members_validated)) {
94 members_type::const_iterator m_iter;
95 for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
96 validate_union_member(*m_iter);
97 }
98 members_validated = true;
99 }
100 }
101
102 void set_union(bool is_union) {
103 is_union_ = is_union;
104 validate_union_members();
105 }
106
107 void set_xsd_all(bool xsd_all) { xsd_all_ = xsd_all; }
108
109 bool get_xsd_all() const { return xsd_all_; }
110
111 bool append(t_field* elem) {
112 typedef members_type::iterator iter_type;
113 std::pair<iter_type, iter_type> bounds = std::equal_range(members_in_id_order_.begin(),
114 members_in_id_order_.end(),
115 elem,
116 t_field::key_compare());
117 if (bounds.first != bounds.second) {
118 return false;
119 }
120 // returns false when there is a conflict of field names
121 if (get_field_by_name(elem->get_name()) != nullptr) {
122 return false;
123 }
124 members_.push_back(elem);
125 members_in_id_order_.insert(bounds.second, elem);
126 validate_union_member(elem);
127 return true;
128 }
129
130 const members_type& get_members() const { return members_; }
131
132 const members_type& get_sorted_members() const { return members_in_id_order_; }
133
134 bool is_struct() const override { return !is_xception_; }
135
136 bool is_xception() const override { return is_xception_; }
137
138 bool is_union() const { return is_union_; }
139
140 t_field* get_field_by_name(std::string field_name) {
141 return const_cast<t_field*>(const_cast<const t_struct&>(*this).get_field_by_name(field_name));
142 }
143
144 const t_field* get_field_by_name(std::string field_name) const {
145 members_type::const_iterator m_iter;
146 for (m_iter = members_in_id_order_.begin(); m_iter != members_in_id_order_.end(); ++m_iter) {
147 if ((*m_iter)->get_name() == field_name) {
148 return *m_iter;
149 }
150 }
151 return nullptr;
152 }
153
154private:
155 members_type members_;
156 members_type members_in_id_order_;
157 bool is_xception_;
158 bool is_union_;
159 bool members_validated;
160 int members_with_value;
161
162 bool xsd_all_;
163};
164
165#endif