xsd_attrs are a FieldList now, so you can have multiple of them and they are typed

Reviewed By: xsd


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664984 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_xsd_generator.cc b/compiler/cpp/src/generate/t_xsd_generator.cc
index 06803ec..4c31d6c 100644
--- a/compiler/cpp/src/generate/t_xsd_generator.cc
+++ b/compiler/cpp/src/generate/t_xsd_generator.cc
@@ -66,7 +66,7 @@
 void t_xsd_generator::generate_element(ostream& out,
                                        string name,
                                        t_type* ttype,
-                                       vector<string> attrs,
+                                       t_struct* attrs,
                                        bool optional,
                                        bool nillable,
                                        bool list_element) {
@@ -79,7 +79,7 @@
     indent(out) <<
       "<xsd:element name=\"" << name << "\"" << soptional << snillable << ">" << endl;
     indent_up();
-    if (attrs.size() == 0 && ttype->is_void()) {
+    if (attrs == NULL && ttype->is_void()) {
       indent(out) << 
         "<xsd:complexType />" << endl;
     } else {
@@ -97,14 +97,17 @@
           subname = type_name(subtype);
         }
         f_php_ << "$GLOBALS['" << program_->get_name() << "_xsd_elt_" << name << "'] = '" << subname << "';" << endl;
-        generate_element(out, subname, subtype, vector<string>(), false, false, true);
+        generate_element(out, subname, subtype, NULL, false, false, true);
         indent_down();
         indent(out) << "</xsd:sequence>" << endl;
         indent(out) << "<xsd:attribute name=\"list\" type=\"xsd:boolean\" />" << endl;
       }
-      vector<string>::iterator a_iter;
-      for (a_iter = attrs.begin(); a_iter != attrs.end(); ++a_iter) {
-        indent(out) << "<xsd:attribute name=\"" << (*a_iter) << "\" type=\"xsd:boolean\" />" << endl;
+      if (attrs != NULL) {
+        const vector<t_field*>& members = attrs->get_members();
+        vector<t_field*>::const_iterator a_iter;
+        for (a_iter = members.begin(); a_iter != members.end(); ++a_iter) {
+          indent(out) << "<xsd:attribute name=\"" << (*a_iter)->get_name() << "\" type=\"" << type_name((*a_iter)->get_type()) << "\" />" << endl;
+        }
       }
       indent_down();
       indent(out) <<
@@ -114,7 +117,7 @@
     indent(out) <<
       "</xsd:element>" << endl;
   } else {
-    if (attrs.size() == 0) {
+    if (attrs == NULL) {
       indent(out) <<
         "<xsd:element name=\"" << name << "\"" << " type=\"" << type_name(ttype) << "\"" << soptional << snillable << " />" << endl;
     } else {
@@ -127,9 +130,10 @@
       indent_up();
       indent(out) << "<xsd:extension base=\"" << type_name(ttype) << "\">" << endl;
       indent_up();
-      vector<string>::iterator a_iter;
-      for (a_iter = attrs.begin(); a_iter != attrs.end(); ++a_iter) {
-        indent(out) << "<xsd:attribute name=\"" << (*a_iter) << "\" type=\"xsd:boolean\" />" << endl;
+      const vector<t_field*>& members = attrs->get_members();
+      vector<t_field*>::const_iterator a_iter;
+      for (a_iter = members.begin(); a_iter != members.end(); ++a_iter) {
+        indent(out) << "<xsd:attribute name=\"" << (*a_iter)->get_name() << "\" type=\"" << type_name((*a_iter)->get_type()) << "\" />" << endl;
       }
       indent_down();
       indent(out) << "</xsd:extension>" << endl;
diff --git a/compiler/cpp/src/generate/t_xsd_generator.h b/compiler/cpp/src/generate/t_xsd_generator.h
index 21e74fb..2c633b9 100644
--- a/compiler/cpp/src/generate/t_xsd_generator.h
+++ b/compiler/cpp/src/generate/t_xsd_generator.h
@@ -40,7 +40,7 @@
 
  private:
 
-  void generate_element(std::ostream& out, std::string name, t_type* ttype, std::vector<std::string> attrs=std::vector<std::string>(), bool optional=false, bool nillable=false, bool list_element=false);
+  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 ns(std::string in, std::string ns) {
     return ns + ":" + in;
diff --git a/compiler/cpp/src/parse/t_field.h b/compiler/cpp/src/parse/t_field.h
index dfa5cac..65a75d3 100644
--- a/compiler/cpp/src/parse/t_field.h
+++ b/compiler/cpp/src/parse/t_field.h
@@ -3,6 +3,9 @@
 
 #include <string>
 
+// Forward declare for xsd_attrs
+class t_struct;
+
 /**
  * Class to represent a field in a thrift structure. A field has a data type,
  * a symbolic name, and a numeric identifier.
@@ -17,7 +20,8 @@
     key_(0),
     value_(NULL),
     xsd_optional_(false),
-    xsd_nillable_(false) {}
+    xsd_nillable_(false),
+    xsd_attrs_(NULL) {}
 
   t_field(t_type* type, std::string name, int32_t key) :
     type_(type),
@@ -25,7 +29,8 @@
     key_(key),
     value_(NULL),
     xsd_optional_(false),
-    xsd_nillable_(false) {}
+    xsd_nillable_(false),
+    xsd_attrs_(NULL) {}
 
   ~t_field() {}
 
@@ -65,11 +70,11 @@
     return xsd_nillable_;
   }
 
-  void add_xsd_attr(std::string attr) {
-    xsd_attrs_.push_back(attr);
+  void set_xsd_attrs(t_struct* xsd_attrs) {
+    xsd_attrs_ = xsd_attrs;
   }
 
-  const std::vector<std::string>& get_xsd_attrs() {
+  t_struct* get_xsd_attrs() {
     return xsd_attrs_;
   }
 
@@ -94,7 +99,7 @@
 
   bool xsd_optional_;
   bool xsd_nillable_;
-  std::vector<std::string> xsd_attrs_;
+  t_struct* xsd_attrs_;
 
   std::string doc_;                                           
   bool has_doc_;                                              
diff --git a/compiler/cpp/src/thrifty.yy b/compiler/cpp/src/thrifty.yy
index c1d383b..19f1ba8 100644
--- a/compiler/cpp/src/thrifty.yy
+++ b/compiler/cpp/src/thrifty.yy
@@ -157,7 +157,7 @@
 %type<tbool>     XsdAll
 %type<tbool>     XsdOptional
 %type<tbool>     XsdNillable
-%type<id>        XsdAttributes
+%type<tstruct>   XsdAttributes
 %type<id>        CppType
 
 %type<tdoc>      DocTextOptional
@@ -530,9 +530,9 @@
     }
 
 XsdAttributes:
-  tok_xsd_attrs tok_identifier
+  tok_xsd_attrs '{' FieldList '}'
     {
-      $$ = $2;
+      $$ = $3;
     }
 |
     {
@@ -660,7 +660,7 @@
         $$->set_doc($1);
       }
       if ($8 != NULL) {
-        $$->add_xsd_attr($8);
+        $$->set_xsd_attrs($8);
       }
     }