Commit 07f0e3e9 authored by Botond Baranyi's avatar Botond Baranyi
Browse files

Added standard-compliant syntax for JSON attributes (bug 529888)



Change-Id: I6f6d50bac7011891db7b430ce3ab09f98222e9df
Signed-off-by: Botond Baranyi's avatarBotond Baranyi <botond.baranyi@ericsson.com>
parent f734a2a6
......@@ -14,6 +14,7 @@
#include "Type.hh"
#include "Value.hh"
#include "CompilerError.hh"
#include "ttcn3/RawAST.hh"
namespace Common {
......
......@@ -51,6 +51,7 @@
#include "ttcn3/Ttcnstuff.hh"
#include "ttcn3/TtcnTemplate.hh"
#include "ttcn3/Templatestuff.hh"
#include "ttcn3/RawAST.hh"
#include "../common/static_check.h"
#include "PredefFunc.hh"
......
......@@ -34,7 +34,6 @@
#include "Int.hh"
#include "subtype.hh"
#include "ttcn3/rawASTspec.h"
#include "ttcn3/RawAST.hh"
#include "ttcn3/TextAST.hh"
#include "ttcn3/BerAST.hh"
#include "ttcn3/JsonAST.hh"
......@@ -42,6 +41,7 @@
#include <float.h>
class XerAttributes;
class RawAST;
enum namedbool { INCOMPLETE_NOT_ALLOWED = 0, INCOMPLETE_ALLOWED = 1, WARNING_FOR_INCOMPLETE = 2,
NO_SUB_CHK = 0, SUB_CHK = 3,
OMIT_NOT_ALLOWED = 0, OMIT_ALLOWED = 4,
......
......@@ -49,6 +49,7 @@
#include "asn1/Tag.hh"
#include "XerAttributes.hh"
#include "ttcn3/RawAST.hh"
#include <ctype.h>
#include <stdlib.h> // for qsort
......@@ -1043,7 +1044,7 @@ void Type::chk_this_variant(const Ttcn::SingleWithAttrib* swa, bool global)
}
int ret = parse_rawAST(rawattrib, textattrib, xerattrib, berattrib, jsonattrib,
swa->get_attribSpec(), get_length_multiplier(), my_scope->get_scope_mod(),
raw_found, text_found, xer_found, ber_found, json_found);
raw_found, text_found, xer_found, ber_found, json_found, coding);
bool mismatch = false;
if (ber_found || raw_found || text_found || xer_found || json_found) {
switch (coding) {
......
......@@ -36,6 +36,7 @@
#include "ttcn3/Attributes.hh"
#include "ttcn3/signature.h"
#include "XerAttributes.hh"
#include "ttcn3/RawAST.hh"
#include "asn1/TableConstraint.hh"
#include "asn1/Object.hh"
......
......@@ -22,6 +22,7 @@
#include "../Setting.hh"
#include "../Identifier.hh"
#include "../../common/CharCoding.hh"
#include "../Type.hh"
class XerAttributes;
class TextAST;
......@@ -154,13 +155,16 @@ public:
* @param[out] text_found set to \c true if a TEXT attribute was found
* @param[out] xer_found set to \c true if a XER attribute was found
* @param[out] json_found set to \c true if a JSON attribute was found
* @param[in] sel_codec indicates which codec to use for attributes that
* belong to multiple codecs
* @return the return value of rawAST_parse: 0 for success, 1 for error,
* 2 for out of memory.
*/
extern int parse_rawAST(RawAST *par, TextAST *textpar, XerAttributes *xerpar,
BerAST *berpar, JsonAST* jsonpar, const Ttcn::AttributeSpec& attrib,
int l_multip, const Common::Module* mod, bool &raw_found, bool &text_found,
bool &xer_found, bool &ber_found, bool &json_found);
bool &xer_found, bool &ber_found, bool &json_found,
Common::Type::MessageEncodingType_t par_codec = Common::Type::CT_UNDEF);
extern void copy_rawAST_to_struct(RawAST *from, raw_attrib_struct *to);
extern void free_raw_attrib_struct(raw_attrib_struct *raw);
extern int compare_raw_attrib(RawAST *a, RawAST *b);
......
......@@ -59,6 +59,7 @@ bool xer_f;
bool ber_f;
bool json_f;
int length_multiplier;
Common::Type::MessageEncodingType_t selected_codec;
extern void rawAST_error(const char *str); /* defined in this file */
extern int rawAST_parse(); /* in rawAST.tab.cc, generated from rawAST.y */
......@@ -450,8 +451,10 @@ anyType RETURN(XSDanyType);
} /* end XER keywords in INITIAL */
/* prefix for legacy JSON attributes */
JSON { BEGIN(jsoncodec); RETURN(XKWjson); }
/* legacy JSON attributes */
<jsoncodec>{
[: \t] RETURN(*yytext);
omit RETURN(XKWomit);
......@@ -483,6 +486,17 @@ number RETURN(XKWnumber);
[)] { BEGIN(jsoncodec); RETURN(XJsonValueEnd); }
[\"][\"] { yylval.str = mcopystr("\\\""); RETURN(XJsonValueSegment); }
[^\"\\)]+ { yylval.str = mcopystr(yytext); RETURN(XJsonValueSegment); }
}
/* tokens for new JSON attributes (standard-compliant) */
<INITIAL>{
asValue RETURN(XAsValueKeyword);
default { BEGIN(jsoncodec); RETURN(XKWdefault); }
number RETURN(XKWnumber);
extend { BEGIN(jsoncodec); RETURN(XKWextend); }
metainfo RETURN(XKWmetainfo);
for RETURN(XKWfor);
unbound RETURN(XKWunbound);
}
<INITIAL>{
......@@ -656,7 +670,8 @@ void free_rawAST_tag_list(rawAST_tag_list* spec){
int parse_rawAST(RawAST *par, TextAST *textpar, XerAttributes *xerpar,
BerAST* berpar, JsonAST* jsonpar, const Ttcn::AttributeSpec& attrib,
int l_multip, const Common::Module* mod, bool &raw_found, bool &text_found,
bool &xer_found, bool &ber_found, bool &json_found)
bool &xer_found, bool &ber_found, bool &json_found,
Common::Type::MessageEncodingType_t par_codec /* = Common::Type::CT_UNDEF */)
{
rawstruct=par;
textstruct=textpar;
......@@ -665,6 +680,7 @@ int parse_rawAST(RawAST *par, TextAST *textpar, XerAttributes *xerpar,
jsonstruct = jsonpar;
length_multiplier=l_multip;
selected_codec = par_codec;
infile = attrib.get_filename();
current_line = attrib.get_first_line();
/* skip the leading " of the attribute value */
......
......@@ -31,6 +31,7 @@
#include "../XerAttributes.hh"
#include "BerAST.hh"
#include "JsonAST.hh"
#include "../main.hh"
extern void rawAST_error(const char *str);
extern int rawAST_lex();
......@@ -38,6 +39,7 @@ extern int rawAST_lex();
extern RawAST* rawstruct;
extern Common::Module *mymod;
extern int length_multiplier;
extern Common::Type::MessageEncodingType_t selected_codec;
extern TextAST *textstruct;
extern bool raw_f;
extern bool text_f;
......@@ -291,6 +293,7 @@ static void yyprint(FILE *file, int type, const YYSTYPE& value);
%token XJsonValueStart "("
%token XJsonValueEnd ")"
%token XJsonValueSegment "JSON value"
%token XAsValueKeyword "asValue"
%type <enumval>
......@@ -427,6 +430,8 @@ XAttribSpec : /* Empty */
{ }
| XBERattributes
{ }
| JSONattributes
{ }
;
XBERattributes :
......@@ -1355,18 +1360,54 @@ XERattribute:
| fractionDigits { xerstruct->fractionDigits_ = $1; xerstruct->has_fractionDigits_ = true; }
| XKWlist { xerstruct->list_ = true; }
| name
{ /* overwrites any previous name */
switch (xerstruct->name_.kw_) {
case NamespaceSpecification::NO_MANGLING:
case NamespaceSpecification::CAPITALIZED:
case NamespaceSpecification::UNCAPITALIZED:
case NamespaceSpecification::UPPERCASED:
case NamespaceSpecification::LOWERCASED:
break; // nothing to do
default: // real string, must be freed
Free(xerstruct->name_.nn_);
{
// this handles the "name as '...' " attributes for both the XER and
// JSON codecs
// (overwrites any previously set name)
if (selected_codec == Common::Type::CT_XER) {
switch (xerstruct->name_.kw_) {
case NamespaceSpecification::NO_MANGLING:
case NamespaceSpecification::CAPITALIZED:
case NamespaceSpecification::UNCAPITALIZED:
case NamespaceSpecification::UPPERCASED:
case NamespaceSpecification::LOWERCASED:
break; // nothing to do
default: // real string, must be freed
Free(xerstruct->name_.nn_);
}
xerstruct->name_.nn_ = $1;
}
else {
// treat XML special values and real strings separately
XerAttributes::NameChange special;
special.nn_ = $1;
switch (special.kw_) {
case NamespaceSpecification::NO_MANGLING:
case NamespaceSpecification::CAPITALIZED:
case NamespaceSpecification::UNCAPITALIZED:
case NamespaceSpecification::UPPERCASED:
case NamespaceSpecification::LOWERCASED:
// it's a special value
// JSON: display an error (if using the new codec handling)
// otherwise ignore
if (!legacy_codec_handling &&
selected_codec == Common::Type::CT_JSON) {
Common::Location loc(infile, @$);
loc.error("This format is not supported for the JSON codec");
}
break;
default: // it's a real string
if (selected_codec == Common::Type::CT_JSON) {
Free(jsonstruct->alias);
jsonstruct->alias = $1;
json_f = true;
}
else {
Free($1);
}
break;
}
}
xerstruct->name_.nn_ = $1;
}
| namespace
{ /* overwrites any previous namespace */
......@@ -1612,7 +1653,7 @@ xsddata: /* XSD:something */
;
// JSON encoder
// JSON attributes, with 'JSON:' prefix (legacy attributes)
XJsonDef:
XOptSpaces XKWjson XOptSpaces ':' XOptSpaces XJsonAttribute XOptSpaces
;
......@@ -1632,7 +1673,10 @@ XOmitAsNull:
;
XNameAs:
XKWname XSpaces XKWas XSpaces XJsonAlias { jsonstruct->alias = $5; }
XKWname XSpaces XKWas XSpaces XJsonAlias {
Free(jsonstruct->alias);
jsonstruct->alias = $5;
}
;
XJsonAlias: // include all keywords, so they can be used as aliases for fields, too
......@@ -1694,6 +1738,47 @@ XSpace:
| '\t'
;
// JSON attributes with no prefix (standard-compliant attributes)
JSONattributes:
JSONattribute { json_f = true; }
;
JSONattribute:
JOmitAsNull
/* the name as '...' is handled in the XER attributes section */
| JAsValue
| JDefault
| JExtend
| JMetainfoForUnbound
| JAsNumber
;
JOmitAsNull:
XOmitKeyword XKWas XNullKeyword { jsonstruct->omit_as_null = true; }
;
JAsValue:
XAsValueKeyword { jsonstruct->as_value = true; }
;
JDefault:
XKWdefault XOptSpaces XJsonValue XOptSpaces { jsonstruct->default_value = $3; }
;
JExtend:
XKWextend XOptSpaces XJsonValue XOptSpaces ':' XOptSpaces XJsonValue XOptSpaces
{ jsonstruct->schema_extensions.add(new JsonSchemaExtension($3, $7)); }
;
JMetainfoForUnbound:
XKWmetainfo XKWfor XKWunbound { jsonstruct->metainfo_unbound = true; }
;
JAsNumber:
XKWas XKWnumber { jsonstruct->as_number = true; }
;
%%
/* parse_rawAST(), which calls our rawAST_parse, is over in rawASST.l */
......
......@@ -32,7 +32,8 @@ type record Rec3 { //^In type definition//
}
with {
encode "JSON";
variant "name as uncapitalized"; //Variant attribute is not related to JSON encoding//
variant "attribute"; //Variant attribute is not related to JSON encoding//
variant "name as uncapitalized"; //Variant attribute is not related to JSON encoding// //This format is not supported for the JSON codec//
}
type record Rec4 { //^In type definition//
......
......@@ -160,7 +160,7 @@ type union Thing {
} prod2val
} with {
variant "JSON:as value";
variant (prod2val.productID) "JSON:name as code";
variant (prod2val.productID) "name as 'code'";
variant(unival) "JSON:as value";
}
......@@ -213,8 +213,8 @@ type record OptionalUnions {
Thing uniTtcn optional,
AsnThing uniAsn optional
} with {
variant(uniTtcn) "JSON: omit as null";
variant(uniAsn) " JSON: omit as null ";
variant(uniTtcn) "omit as null";
variant(uniAsn) " omit as null ";
}
type record MetainfoRecord {
......@@ -262,7 +262,7 @@ type set of MetainfoRecord MetainfoSetOf
with { variant "JSON: metainfo for unbound"; }
type float MetainfoArray[3]
with { variant "JSON: metainfo for unbound"; }
with { variant "metainfo for unbound"; }
type record RecAsValue {
integer field
......@@ -288,7 +288,7 @@ type set SetWithAsValueFields {
with {
variant (uni) "JSON: as value";
variant (rec) "JSON: as value";
variant (list[-]) "JSON: as value";
variant (list[-]) "asValue";
}
type record RecWithAsNumber {
......@@ -297,7 +297,7 @@ type record RecWithAsNumber {
}
with {
variant (lengths[-]) "JSON: as number";
variant (days[-]) "JSON: as number";
variant (days[-]) "as number";
}
type union Uni522660 {
......@@ -313,8 +313,8 @@ type record DefaultEmptyStructs {
}
with {
variant (r) "JSON: default({})";
variant (s) "JSON: default({})";
variant (ro) "JSON: default({})";
variant (s) "default({})";
variant (ro) "default({})";
variant (so) "JSON: default({})";
}
......
......@@ -758,4 +758,4 @@ module PortTranslation {
execute(tc_receive_fragmented());
}
}
\ No newline at end of file
}
......@@ -29,7 +29,7 @@ type set Set {
} with {
variant(numbr) " JSON : default (-infinity) ";
variant(buul) " JSON:omit as null ";
variant(os) "JSON:extend(MSB):(first) ";
variant(os) "extend(MSB):(first) ";
}
type union Uni {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment