Add xsd_all keyword to Thrift

Summary: Makes a struct an xsd_all instead of a sequence

Reviewed By: dave


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664929 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 cb184a3..57c9656 100644
--- a/compiler/cpp/src/generate/t_xsd_generator.cc
+++ b/compiler/cpp/src/generate/t_xsd_generator.cc
@@ -26,10 +26,15 @@
 void t_xsd_generator::generate_struct(t_struct* tstruct) {
   vector<t_field*>::const_iterator m_iter; 
   const vector<t_field*>& members = tstruct->get_members();
+  bool xsd_all = tstruct->get_xsd_all();
   
   indent(s_xsd_types_) << "<xsd:complexType name=\"" << tstruct->get_name() << "\">" << endl;
   indent_up();
-  indent(s_xsd_types_) << "<xsd:sequence>" << endl;
+  if (xsd_all) {
+    indent(s_xsd_types_) << "<xsd:all minOccurs=\"0\" maxOccurs=\"1\">" << endl;
+  } else {
+    indent(s_xsd_types_) << "<xsd:sequence>" << endl;
+  }
   indent_up();
   
   for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
@@ -37,7 +42,11 @@
   } 
 
   indent_down();
-  indent(s_xsd_types_) << "</xsd:sequence>" << endl;
+  if (xsd_all) {
+    indent(s_xsd_types_) << "</xsd:all>" << endl;
+  } else {
+    indent(s_xsd_types_) << "</xsd:sequence>" << endl;
+  }
   indent_down();
   indent(s_xsd_types_) <<
     "</xsd:complexType>" << endl <<
diff --git a/compiler/cpp/src/parse/t_struct.h b/compiler/cpp/src/parse/t_struct.h
index ce5f752..bebea2a 100644
--- a/compiler/cpp/src/parse/t_struct.h
+++ b/compiler/cpp/src/parse/t_struct.h
@@ -20,11 +20,13 @@
  public:
   t_struct(t_program* program) :
     t_type(program),
-    is_xception_(false) {}
+    is_xception_(false),
+    xsd_all_(false) {}
 
   t_struct(t_program* program, const std::string& name) :
     t_type(program, name),
-    is_xception_(false) {}
+    is_xception_(false),
+    xsd_all_(false) {}
 
   void set_name(const std::string& name) {
     name_ = name;
@@ -34,6 +36,14 @@
     is_xception_ = is_xception;
   }
 
+  void set_xsd_all(bool xsd_all) {
+    xsd_all_ = xsd_all;
+  }
+
+  bool get_xsd_all() const {
+    return xsd_all_;
+  }
+
   void append(t_field* elem) {
     members_.push_back(elem);
   }
@@ -53,6 +63,9 @@
  private:
   std::vector<t_field*> members_;
   bool is_xception_;
+
+  bool xsd_all_;
+
 };
 
 #endif
diff --git a/compiler/cpp/src/thrift.l b/compiler/cpp/src/thrift.l
index 324c5ea..4f2d542 100644
--- a/compiler/cpp/src/thrift.l
+++ b/compiler/cpp/src/thrift.l
@@ -59,6 +59,7 @@
 "cpp_type"      { return tok_cpp_type;      }
 "java_package"  { return tok_java_package;  }
 "php_namespace" { return tok_php_namespace; }
+"xsd_all"       { return tok_xsd_all;       }
 "include"       { return tok_include;       }
 
 "void"          { return tok_void;          }
diff --git a/compiler/cpp/src/thrift.y b/compiler/cpp/src/thrift.y
index 8dbe621..cfb3e44 100644
--- a/compiler/cpp/src/thrift.y
+++ b/compiler/cpp/src/thrift.y
@@ -66,6 +66,7 @@
 %token tok_cpp_type
 %token tok_php_namespace
 %token tok_java_package
+%token tok_xsd_all
 
 /**
  * Base datatype keywords
@@ -144,6 +145,7 @@
 %type<tstruct>   ThrowsOptional
 %type<tservice>  ExtendsOptional
 %type<tbool>     AsyncOptional
+%type<tbool>     XsdAllOptional
 %type<id>        CppTypeOptional
 
 %%
@@ -440,14 +442,25 @@
     }
 
 Struct:
-  tok_struct tok_identifier '{' FieldList '}'
+  tok_struct tok_identifier XsdAllOptional '{' FieldList '}'
     {
       pdebug("Struct -> tok_struct tok_identifier { FieldList }");
-      $4->set_name($2);
-      $$ = $4;
+      $5->set_name($2);
+      $5->set_xsd_all($3);
+      $$ = $5;
       y_field_val = -1;
     }
 
+XsdAllOptional:
+  tok_xsd_all
+    {
+      $$ = true;
+    }
+|
+    {
+      $$ = false;
+    }
+
 Xception:
   tok_xception tok_identifier '{' FieldList '}'
     {