40 const std::map<std::string, std::string>& parsed_options,
41 const std::string& option_string)
44 (void) parsed_options;
46 out_dir_base_ =
"gen-xsd";
55 void init_generator();
56 void close_generator();
62 void generate_typedef(
t_typedef* ttypedef);
67 void generate_service(
t_service* tservice);
68 void generate_struct(
t_struct* tstruct);
71 void generate_sandesh(
t_sandesh* tsandesh);
76 void generate_element(std::ostream& out, std::string name,
t_type* ttype,
t_struct* attrs=NULL,
bool optional=
false,
bool nillable=
false,
bool list_element=
false);
78 std::string
ns(std::string in, std::string ns) {
82 std::string
xsd(std::string in) {
86 std::string type_name(
t_type* ttype);
105 MKDIR(get_out_dir().c_str());
109 string f_php_name = get_out_dir()+program_->get_name()+
"_xsd.php";
110 f_php_.open(f_php_name.c_str());
116 string f_xsd_name = get_out_dir()+program_->get_name()+
".xsd";
117 f_xsd_.open(f_xsd_name.c_str());
123 f_php_ <<
"?>" << endl;
126 f_xsd_ << s_xsd_types_.str();
132 indent(s_xsd_types_) <<
133 "<xsd:simpleType name=\"" << ttypedef->
get_name() <<
"\">" << endl;
136 indent(s_xsd_types_) <<
137 "<xsd:restriction base=\"" << type_name(ttypedef->
get_type()) <<
"\">" << endl;
139 const vector<string>& values = ((
t_base_type*)ttypedef->
get_type())->get_string_enum_vals();
140 vector<string>::const_iterator v_iter;
141 for (v_iter = values.begin(); v_iter != values.end(); ++v_iter) {
142 indent(s_xsd_types_) <<
143 "<xsd:enumeration value=\"" << (*v_iter) <<
"\" />" << endl;
146 indent(s_xsd_types_) <<
147 "</xsd:restriction>" << endl;
149 indent(s_xsd_types_) <<
150 "<xsd:restriction base=\"" << type_name(ttypedef->
get_type()) <<
"\" />" << endl;
153 indent(s_xsd_types_) <<
154 "</xsd:simpleType>" << endl << endl;
158 vector<t_field*>::const_iterator m_iter;
159 const vector<t_field*>& members = tstruct->
get_members();
162 indent(s_xsd_types_) <<
"<xsd:complexType name=\"" << tstruct->
get_name() <<
"\">" << endl;
165 indent(s_xsd_types_) <<
"<xsd:all>" << endl;
167 indent(s_xsd_types_) <<
"<xsd:sequence>" << endl;
171 for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
172 generate_element(s_xsd_types_, (*m_iter)->get_name(), (*m_iter)->get_type(), (*m_iter)->get_xsd_attrs(), (*m_iter)->get_xsd_optional() || xsd_all, (*m_iter)->get_xsd_nillable());
177 indent(s_xsd_types_) <<
"</xsd:all>" << endl;
179 indent(s_xsd_types_) <<
"</xsd:sequence>" << endl;
182 indent(s_xsd_types_) <<
183 "</xsd:complexType>" << endl <<
188 void t_xsd_generator::generate_sandesh(
t_sandesh* tsandesh) {
189 vector<t_field*>::const_iterator m_iter;
190 const vector<t_field*>& members = tsandesh->
get_members();
191 bool xsd_all =
false;
193 indent(s_xsd_types_) <<
"<xsd:complexType name=\"" << tsandesh->
get_name() <<
"\">" << endl;
196 indent(s_xsd_types_) <<
"<xsd:all>" << endl;
198 indent(s_xsd_types_) <<
"<xsd:sequence>" << endl;
202 for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
203 generate_element(s_xsd_types_, (*m_iter)->get_name(), (*m_iter)->get_type(), (*m_iter)->get_xsd_attrs(), (*m_iter)->get_xsd_optional() || xsd_all, (*m_iter)->get_xsd_nillable());
208 indent(s_xsd_types_) <<
"</xsd:all>" << endl;
210 indent(s_xsd_types_) <<
"</xsd:sequence>" << endl;
213 indent(s_xsd_types_) <<
214 "</xsd:complexType>" << endl <<
226 string sminOccurs = (optional || list_element) ?
" minOccurs=\"0\"" :
"";
227 string smaxOccurs = list_element ?
" maxOccurs=\"unbounded\"" :
"";
228 string soptional = sminOccurs + smaxOccurs;
229 string snillable = nillable ?
" nillable=\"true\"" :
"";
233 "<xsd:element name=\"" << name <<
"\"" << soptional << snillable <<
">" << endl;
235 if (attrs == NULL && ttype->
is_void()) {
237 "<xsd:complexType />" << endl;
240 "<xsd:complexType>" << endl;
243 indent(out) <<
"<xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">" << endl;
248 subname = name +
"_elt";
250 subname = type_name(subtype);
252 f_php_ <<
"$GLOBALS['" << program_->get_name() <<
"_xsd_elt_" << name <<
"'] = '" << subname <<
"';" << endl;
253 generate_element(out, subname, subtype, NULL,
false,
false,
true);
255 indent(out) <<
"</xsd:sequence>" << endl;
256 indent(out) <<
"<xsd:attribute name=\"list\" type=\"xsd:boolean\" />" << endl;
259 const vector<t_field*>& members = attrs->
get_members();
260 vector<t_field*>::const_iterator a_iter;
261 for (a_iter = members.begin(); a_iter != members.end(); ++a_iter) {
262 indent(out) <<
"<xsd:attribute name=\"" << (*a_iter)->get_name() <<
"\" type=\"" << type_name((*a_iter)->get_type()) <<
"\" />" << endl;
267 "</xsd:complexType>" << endl;
271 "</xsd:element>" << endl;
275 "<xsd:element name=\"" << name <<
"\"" <<
" type=\"" << type_name(ttype) <<
"\"" << soptional << snillable <<
" />" << endl;
278 indent(out) <<
"<xsd:element name=\"" << name <<
"\"" << soptional << snillable <<
">" << endl;
280 indent(out) <<
"<xsd:complexType>" << endl;
282 indent(out) <<
"<xsd:complexContent>" << endl;
284 indent(out) <<
"<xsd:extension base=\"" << type_name(ttype) <<
"\">" << endl;
286 const vector<t_field*>& members = attrs->
get_members();
287 vector<t_field*>::const_iterator a_iter;
288 for (a_iter = members.begin(); a_iter != members.end(); ++a_iter) {
289 indent(out) <<
"<xsd:attribute name=\"" << (*a_iter)->get_name() <<
"\" type=\"" << type_name((*a_iter)->get_type()) <<
"\" />" << endl;
292 indent(out) <<
"</xsd:extension>" << endl;
294 indent(out) <<
"</xsd:complexContent>" << endl;
296 indent(out) <<
"</xsd:complexType>" << endl;
298 indent(out) <<
"</xsd:element>" << endl;
305 string f_xsd_name = get_out_dir()+tservice->
get_name()+
".xsd";
306 f_xsd_.open(f_xsd_name.c_str());
308 string ns = program_->get_namespace(
"xsd");
310 ns =
" targetNamespace=\"" + ns +
"\" xmlns=\"" + ns +
"\" " +
311 "elementFormDefault=\"qualified\"";
316 "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" << endl <<
317 "<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" << ns <<
">" << endl <<
319 "<!-- Yo yo yo, this XSD woz be generated by Thrift. -->" << endl <<
323 indent(f_xsd_) << s_xsd_types_.str();
326 map<string, t_struct*> all_xceptions;
330 vector<t_function*>::iterator f_iter;
331 for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
332 string elemname = (*f_iter)->get_name() +
"_response";
333 t_type* returntype = (*f_iter)->get_returntype();
334 generate_element(f_xsd_, elemname, returntype);
337 t_struct* xs = (*f_iter)->get_xceptions();
338 const std::vector<t_field*>& xceptions = xs->
get_members();
339 vector<t_field*>::const_iterator x_iter;
340 for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
341 all_xceptions[(*x_iter)->get_name()] = (
t_struct*)((*x_iter)->get_type());
345 map<string, t_struct*>::iterator ax_iter;
346 for (ax_iter = all_xceptions.begin(); ax_iter != all_xceptions.end(); ++ax_iter) {
347 generate_element(f_xsd_, ax_iter->first, ax_iter->second);
351 f_xsd_ << endl <<
"</xsd:schema>" << endl;
361 return xsd(base_type_name(((
t_base_type*)ttype)->get_base()));
373 if (ttype->is_sandesh()) {
392 case t_base_type::TYPE_STATIC_CONST_STRING:
virtual bool is_xception() const
t_type * get_type() const
std::string base_type_name(t_base_type::t_base tbase)
static std::string t_base_name(t_base tbase)
virtual bool is_enum() const
virtual bool is_base_type() const
void generate_typedef(t_typedef *ttypedef)
const members_type & get_members()
virtual ~t_xsd_generator()
virtual bool is_container() const
virtual bool is_typedef() const
std::string xsd(std::string in)
virtual bool is_void() const
void generate_enum(t_enum *tenum)
void generate_struct(t_struct *tstruct)
const std::vector< t_function * > & get_functions() const
std::ostringstream s_xsd_types_
virtual const std::string & get_name() const
virtual bool is_list() const
virtual bool is_struct() const
void generate_element(std::ostream &out, std::string name, t_type *ttype, t_struct *attrs=NULL, bool optional=false, bool nillable=false, bool list_element=false)
std::string type_name(t_type *ttype)
t_xsd_generator(t_program *program, const std::map< std::string, std::string > &parsed_options, const std::string &option_string)
void generate_service(t_service *tservice)
virtual bool is_string() const
#define THRIFT_REGISTER_GENERATOR(language, long_name, doc)
std::string ns(std::string in, std::string ns)