From: Mark Slee Date: Fri, 19 Jan 2007 20:09:51 +0000 (+0000) Subject: Allow field elements to be optional in thrift with xsd_optional keyword X-Git-Tag: 0.2.0~1540 X-Git-Url: https://source.supwisdom.com/gerrit/gitweb?a=commitdiff_plain;h=36bfa2e61f6321f6910293d3cf66241fcd66ccfb;p=common%2Fthrift.git Allow field elements to be optional in thrift with xsd_optional keyword Reviewed By: tbr-dave git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664932 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 57c9656a..5d4cfa20 100644 --- a/compiler/cpp/src/generate/t_xsd_generator.cc +++ b/compiler/cpp/src/generate/t_xsd_generator.cc @@ -38,7 +38,7 @@ void t_xsd_generator::generate_struct(t_struct* tstruct) { indent_up(); for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) { - generate_element(s_xsd_types_, (*m_iter)->get_name(), (*m_iter)->get_type()); + generate_element(s_xsd_types_, (*m_iter)->get_name(), (*m_iter)->get_type(), (*m_iter)->get_xsd_optional()); } indent_down(); @@ -55,10 +55,13 @@ void t_xsd_generator::generate_struct(t_struct* tstruct) { void t_xsd_generator::generate_element(ostream& out, string name, - t_type* ttype) { + t_type* ttype, + bool optional) { + string soptional = optional ? " minoccurs=\"0\" maxOccurs=\"1\"" : ""; + if (ttype->is_void() || ttype->is_list()) { indent(out) << - "" << endl; + "" << endl; indent_up(); if (ttype->is_void()) { indent(out) << @@ -87,7 +90,7 @@ void t_xsd_generator::generate_element(ostream& out, "" << endl; } else { indent(out) << - "" << endl; + "" << endl; } } diff --git a/compiler/cpp/src/generate/t_xsd_generator.h b/compiler/cpp/src/generate/t_xsd_generator.h index fc39765b..35bcf933 100644 --- a/compiler/cpp/src/generate/t_xsd_generator.h +++ b/compiler/cpp/src/generate/t_xsd_generator.h @@ -40,7 +40,7 @@ class t_xsd_generator : public t_generator { private: - void generate_element(std::ostream& out, std::string name, t_type* ttype); + void generate_element(std::ostream& out, std::string name, t_type* ttype, bool optional=false); std::string ns(std::string in, std::string ns) { return ns + ":" + in; diff --git a/compiler/cpp/src/main.cc b/compiler/cpp/src/main.cc index 2fbf913b..48552e62 100644 --- a/compiler/cpp/src/main.cc +++ b/compiler/cpp/src/main.cc @@ -435,6 +435,7 @@ void parse(t_program* program, t_program* parent_program) { g_program = program; g_scope = program->scope(); try { + yylineno = 1; if (yyparse() != 0) { failure("Parser error during include pass."); } @@ -462,6 +463,7 @@ void parse(t_program* program, t_program* parent_program) { failure("Could not open input file: \"%s\"", path.c_str()); } pverbose("Parsing %s for types\n", path.c_str()); + yylineno = 1; if (yyparse() != 0) { failure("Parser error during types pass."); } diff --git a/compiler/cpp/src/parse/t_field.h b/compiler/cpp/src/parse/t_field.h index 93e14d84..35414efe 100644 --- a/compiler/cpp/src/parse/t_field.h +++ b/compiler/cpp/src/parse/t_field.h @@ -14,12 +14,14 @@ class t_field { t_field(t_type* type, std::string name) : type_(type), name_(name), - key_(0) {} + key_(0), + xsd_optional_(false) {} t_field(t_type* type, std::string name, int32_t key) : type_(type), name_(name), - key_(key) {} + key_(key), + xsd_optional_(false) {} ~t_field() {} @@ -35,10 +37,21 @@ class t_field { return key_; } + void set_xsd_optional(bool xsd_optional) { + xsd_optional_ = xsd_optional; + } + + bool get_xsd_optional() const { + return xsd_optional_; + } + private: t_type* type_; std::string name_; int32_t key_; + + bool xsd_optional_; + }; #endif diff --git a/compiler/cpp/src/thrift.l b/compiler/cpp/src/thrift.l index b7008c69..80cbf878 100644 --- a/compiler/cpp/src/thrift.l +++ b/compiler/cpp/src/thrift.l @@ -60,6 +60,7 @@ sliteral ("'"[^']*"'") "java_package" { return tok_java_package; } "php_namespace" { return tok_php_namespace; } "xsd_all" { return tok_xsd_all; } +"xsd_optional" { return tok_xsd_optional; } "include" { return tok_include; } "void" { return tok_void; } diff --git a/compiler/cpp/src/thrift.y b/compiler/cpp/src/thrift.y index fe56dad9..d8f34355 100644 --- a/compiler/cpp/src/thrift.y +++ b/compiler/cpp/src/thrift.y @@ -67,6 +67,7 @@ int y_field_val = -1; %token tok_php_namespace %token tok_java_package %token tok_xsd_all +%token tok_xsd_optional /** * Base datatype keywords @@ -143,11 +144,12 @@ int y_field_val = -1; %type FunctionType %type FunctionList -%type ThrowsOptional -%type ExtendsOptional -%type AsyncOptional -%type XsdAllOptional -%type CppTypeOptional +%type Throws +%type Extends +%type Async +%type XsdAll +%type XsdOptional +%type CppType %% @@ -443,7 +445,7 @@ ConstMapContents: } Struct: - tok_struct tok_identifier XsdAllOptional '{' FieldList '}' + tok_struct tok_identifier XsdAll '{' FieldList '}' { pdebug("Struct -> tok_struct tok_identifier { FieldList }"); $5->set_name($2); @@ -452,7 +454,7 @@ Struct: y_field_val = -1; } -XsdAllOptional: +XsdAll: tok_xsd_all { $$ = true; @@ -462,6 +464,16 @@ XsdAllOptional: $$ = false; } +XsdOptional: + tok_xsd_optional + { + $$ = true; + } +| + { + $$ = false; + } + Xception: tok_xception tok_identifier '{' FieldList '}' { @@ -473,7 +485,7 @@ Xception: } Service: - tok_service tok_identifier ExtendsOptional '{' FunctionList '}' + tok_service tok_identifier Extends '{' FunctionList '}' { pdebug("Service -> tok_service tok_identifier { FunctionList }"); $$ = $5; @@ -481,10 +493,10 @@ Service: $$->set_extends($3); } -ExtendsOptional: +Extends: tok_extends tok_identifier { - pdebug("ExtendsOptional -> tok_extends tok_identifier"); + pdebug("Extends -> tok_extends tok_identifier"); $$ = NULL; if (g_parse_mode == PROGRAM) { $$ = g_scope->get_service($2); @@ -513,14 +525,14 @@ FunctionList: } Function: - AsyncOptional FunctionType tok_identifier '(' FieldList ')' ThrowsOptional CommaOrSemicolonOptional + Async FunctionType tok_identifier '(' FieldList ')' Throws CommaOrSemicolonOptional { $5->set_name(std::string($3) + "_args"); $$ = new t_function($2, $3, $5, $7, $1); y_field_val = -1; } -AsyncOptional: +Async: tok_async { $$ = true; @@ -530,10 +542,10 @@ AsyncOptional: $$ = false; } -ThrowsOptional: +Throws: tok_throws '(' FieldList ')' { - pdebug("ThrowsOptional -> tok_throws ( FieldList )"); + pdebug("Throws -> tok_throws ( FieldList )"); $$ = $3; } | @@ -555,7 +567,7 @@ FieldList: } Field: - tok_int_constant ':' FieldType tok_identifier CommaOrSemicolonOptional + tok_int_constant ':' FieldType tok_identifier XsdOptional CommaOrSemicolonOptional { pdebug("tok_int_constant : Field -> FieldType tok_identifier"); if ($1 <= 0) { @@ -563,12 +575,14 @@ Field: $1 = y_field_val--; } $$ = new t_field($3, $4, $1); + $$->set_xsd_optional($5); } -| FieldType tok_identifier CommaOrSemicolonOptional +| FieldType tok_identifier XsdOptional CommaOrSemicolonOptional { pdebug("Field -> FieldType tok_identifier"); pwarning(2, "No field key specified for '%s', resulting protocol may have conflicts or not be backwards compatible!\n", $2); $$ = new t_field($1, $2, y_field_val--); + $$->set_xsd_optional($3); } | FieldType tok_identifier '=' tok_int_constant CommaOrSemicolonOptional { @@ -692,7 +706,7 @@ ContainerType: } MapType: - tok_map CppTypeOptional '<' FieldType ',' FieldType '>' + tok_map CppType '<' FieldType ',' FieldType '>' { pdebug("MapType -> tok_map "); $$ = new t_map($4, $6); @@ -702,7 +716,7 @@ MapType: } SetType: - tok_set CppTypeOptional '<' FieldType '>' + tok_set CppType '<' FieldType '>' { pdebug("SetType -> tok_set"); $$ = new t_set($4); @@ -712,7 +726,7 @@ SetType: } ListType: - tok_list '<' FieldType '>' CppTypeOptional + tok_list '<' FieldType '>' CppType { pdebug("ListType -> tok_list"); $$ = new t_list($3); @@ -721,7 +735,7 @@ ListType: } } -CppTypeOptional: +CppType: '[' tok_cpp_type tok_literal ']' { $$ = $3;