summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/Parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Slice/Parser.cpp')
-rwxr-xr-xcpp/src/Slice/Parser.cpp257
1 files changed, 228 insertions, 29 deletions
diff --git a/cpp/src/Slice/Parser.cpp b/cpp/src/Slice/Parser.cpp
index 87ff6f21c9f..e7ecd451617 100755
--- a/cpp/src/Slice/Parser.cpp
+++ b/cpp/src/Slice/Parser.cpp
@@ -40,9 +40,31 @@ string readWriteAttribute[] = { "read", "write" };
string txAttribute[] = { "supports", "mandatory", "required", "never" };
enum { Supports, Mandatory, Required, Never };
-}
+DataMemberList
+filterOrderedOptionalDataMembers(const DataMemberList& members)
+{
+ class SortFn
+ {
+ public:
+ static bool compare(const DataMemberPtr& lhs, const DataMemberPtr& rhs)
+ {
+ return lhs->tag() < rhs->tag();
+ }
+ };
+ DataMemberList result;
+ for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p)
+ {
+ if((*p)->optional())
+ {
+ result.push_back(*p);
+ }
+ }
+ result.sort(SortFn::compare);
+ return result;
+}
+}
namespace Slice
{
@@ -427,6 +449,42 @@ Slice::Contained::addMetaData(const string& s)
_metaData.push_back(s);
}
+FormatType
+Slice::Contained::parseFormatMetaData(const list<string>& metaData)
+{
+ FormatType result = DefaultFormat;
+
+ string tag;
+ string prefix = "format:";
+ for(list<string>::const_iterator p = metaData.begin(); p != metaData.end(); ++p)
+ {
+ if(p->find(prefix) == 0)
+ {
+ tag = *p;
+ break;
+ }
+ }
+
+ if(!tag.empty())
+ {
+ tag = tag.substr(prefix.size());
+ if(tag == "compact")
+ {
+ result = CompactFormat;
+ }
+ else if(tag == "sliced")
+ {
+ result = SlicedFormat;
+ }
+ else if(tag != "default") // TODO: Allow "default" to be specified as a format value?
+ {
+ // TODO: How to handle invalid format?
+ }
+ }
+
+ return result;
+}
+
bool
Slice::Contained::operator<(const Contained& rhs) const
{
@@ -2658,7 +2716,7 @@ Slice::ClassDecl::usesClasses() const
size_t
Slice::ClassDecl::minWireSize() const
{
- return 4; // At least four bytes for an instance, if the instance is marshaled as an index.
+ return 1; // At least four bytes for an instance, if the instance is marshaled as an index.
}
bool
@@ -2905,6 +2963,8 @@ Slice::ClassDef::destroy()
OperationPtr
Slice::ClassDef::createOperation(const string& name,
const TypePtr& returnType,
+ bool optional,
+ int tag,
Operation::Mode mode)
{
checkIdentifier(name);
@@ -3003,14 +3063,15 @@ Slice::ClassDef::createOperation(const string& name,
}
_hasOperations = true;
- OperationPtr op = new Operation(this, name, returnType, mode);
+ OperationPtr op = new Operation(this, name, returnType, optional, tag, mode);
_contents.push_back(op);
return op;
}
DataMemberPtr
-Slice::ClassDef::createDataMember(const string& name, const TypePtr& type, const SyntaxTreeBasePtr& defaultValueType,
- const string& defaultValue, const string& defaultLiteral)
+Slice::ClassDef::createDataMember(const string& name, const TypePtr& type, bool optional, int tag,
+ const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue,
+ const string& defaultLiteral)
{
checkIdentifier(name);
@@ -3152,8 +3213,25 @@ Slice::ClassDef::createDataMember(const string& name, const TypePtr& type, const
}
}
+ if(optional)
+ {
+ //
+ // Validate the tag.
+ //
+ DataMemberList dml = allDataMembers();
+ for(DataMemberList::iterator q = dml.begin(); q != dml.end(); ++q)
+ {
+ if((*q)->optional() && tag == (*q)->tag())
+ {
+ string msg = "tag for optional data member `" + name + "' is already in use";
+ _unit->error(msg);
+ break;
+ }
+ }
+ }
+
_hasDataMembers = true;
- DataMemberPtr member = new DataMember(this, name, type, dlt, dv, dl);
+ DataMemberPtr member = new DataMember(this, name, type, optional, tag, dlt, dv, dl);
_contents.push_back(member);
return member;
}
@@ -3230,6 +3308,12 @@ Slice::ClassDef::dataMembers() const
return result;
}
+DataMemberList
+Slice::ClassDef::orderedOptionalDataMembers() const
+{
+ return filterOrderedOptionalDataMembers(dataMembers());
+}
+
//
// Return the data members of this class and its parent classes, in base-to-derived order.
//
@@ -3399,6 +3483,20 @@ Slice::ClassDef::hasDefaultValues() const
return false;
}
+bool
+Slice::ClassDef::inheritsMetaData(const string& meta) const
+{
+ for(ClassList::const_iterator p = _bases.begin(); p != _bases.end(); ++p)
+ {
+ if((*p)->hasMetaData(meta) || (*p)->inheritsMetaData(meta))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
Contained::ContainedType
Slice::ClassDef::containedType() const
{
@@ -3517,8 +3615,9 @@ Slice::Exception::destroy()
}
DataMemberPtr
-Slice::Exception::createDataMember(const string& name, const TypePtr& type, const SyntaxTreeBasePtr& defaultValueType,
- const string& defaultValue, const string& defaultLiteral)
+Slice::Exception::createDataMember(const string& name, const TypePtr& type, bool optional, int tag,
+ const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue,
+ const string& defaultLiteral)
{
checkIdentifier(name);
@@ -3649,7 +3748,24 @@ Slice::Exception::createDataMember(const string& name, const TypePtr& type, cons
}
}
- DataMemberPtr p = new DataMember(this, name, type, dlt, dv, dl);
+ if(optional)
+ {
+ //
+ // Validate the tag.
+ //
+ DataMemberList dml = allDataMembers();
+ for(DataMemberList::iterator q = dml.begin(); q != dml.end(); ++q)
+ {
+ if((*q)->optional() && tag == (*q)->tag())
+ {
+ string msg = "tag for optional data member `" + name + "' is already in use";
+ _unit->error(msg);
+ break;
+ }
+ }
+ }
+
+ DataMemberPtr p = new DataMember(this, name, type, optional, tag, dlt, dv, dl);
_contents.push_back(p);
return p;
}
@@ -3669,6 +3785,12 @@ Slice::Exception::dataMembers() const
return result;
}
+DataMemberList
+Slice::Exception::orderedOptionalDataMembers() const
+{
+ return filterOrderedOptionalDataMembers(dataMembers());
+}
+
//
// Return the data members of this exception and its parent exceptions, in base-to-derived order.
//
@@ -3828,6 +3950,17 @@ Slice::Exception::hasDefaultValues() const
return false;
}
+bool
+Slice::Exception::inheritsMetaData(const string& meta) const
+{
+ if(_base && (_base->hasMetaData(meta) || _base->inheritsMetaData(meta)))
+ {
+ return true;
+ }
+
+ return false;
+}
+
string
Slice::Exception::kindOf() const
{
@@ -3858,8 +3991,9 @@ Slice::Exception::Exception(const ContainerPtr& container, const string& name, c
// ----------------------------------------------------------------------
DataMemberPtr
-Slice::Struct::createDataMember(const string& name, const TypePtr& type, const SyntaxTreeBasePtr& defaultValueType,
- const string& defaultValue, const string& defaultLiteral)
+Slice::Struct::createDataMember(const string& name, const TypePtr& type, bool optional, int tag,
+ const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue,
+ const string& defaultLiteral)
{
checkIdentifier(name);
@@ -3972,7 +4106,24 @@ Slice::Struct::createDataMember(const string& name, const TypePtr& type, const S
}
}
- DataMemberPtr p = new DataMember(this, name, type, dlt, dv, dl);
+ if(optional)
+ {
+ //
+ // Validate the tag.
+ //
+ DataMemberList dml = dataMembers();
+ for(DataMemberList::iterator q = dml.begin(); q != dml.end(); ++q)
+ {
+ if((*q)->optional() && tag == (*q)->tag())
+ {
+ string msg = "tag for optional data member `" + name + "' is already in use";
+ _unit->error(msg);
+ break;
+ }
+ }
+ }
+
+ DataMemberPtr p = new DataMember(this, name, type, optional, tag, dlt, dv, dl);
_contents.push_back(p);
return p;
}
@@ -4443,22 +4594,13 @@ Slice::Enum::usesClasses() const
size_t
Slice::Enum::minWireSize() const
{
- size_t sz = _enumerators.size();
- if(sz <= 0x7f)
- {
- return 1;
- }
- if(sz <= 0x7fff)
- {
- return 2;
- }
- return 4;
+ return 1;
}
bool
Slice::Enum::isVariableLength() const
{
- return false;
+ return true;
}
string
@@ -4603,6 +4745,18 @@ Slice::Operation::returnType() const
return _returnType;
}
+bool
+Slice::Operation::returnIsOptional() const
+{
+ return _returnIsOptional;
+}
+
+int
+Slice::Operation::returnTag() const
+{
+ return _returnTag;
+}
+
Operation::Mode
Slice::Operation::mode() const
{
@@ -4623,7 +4777,7 @@ Slice::Operation::sendMode() const
}
ParamDeclPtr
-Slice::Operation::createParamDecl(const string& name, const TypePtr& type, bool isOutParam)
+Slice::Operation::createParamDecl(const string& name, const TypePtr& type, bool isOutParam, bool optional, int tag)
{
checkIdentifier(name);
@@ -4722,7 +4876,7 @@ Slice::Operation::createParamDecl(const string& name, const TypePtr& type, bool
_unit->error(msg);
}
- ParamDeclPtr p = new ParamDecl(this, name, type, isOutParam);
+ ParamDeclPtr p = new ParamDecl(this, name, type, isOutParam, optional, tag);
_contents.push_back(p);
return p;
}
@@ -4980,6 +5134,18 @@ Slice::Operation::attributes() const
}
}
+FormatType
+Slice::Operation::format() const
+{
+ FormatType format = parseFormatMetaData(getMetaData());
+ if(format == DefaultFormat)
+ {
+ ContainedPtr cont = ContainedPtr::dynamicCast(container());
+ assert(cont);
+ format = parseFormatMetaData(cont->getMetaData());
+ }
+ return format;
+}
string
Slice::Operation::kindOf() const
@@ -4996,11 +5162,15 @@ Slice::Operation::visit(ParserVisitor* visitor, bool)
Slice::Operation::Operation(const ContainerPtr& container,
const string& name,
const TypePtr& returnType,
+ bool returnIsOptional,
+ int returnTag,
Mode mode) :
SyntaxTreeBase(container->unit()),
Contained(container, name),
Container(container->unit()),
_returnType(returnType),
+ _returnIsOptional(returnIsOptional),
+ _returnTag(returnTag),
_mode(mode)
{
if(_unit->profile() == IceE)
@@ -5041,6 +5211,18 @@ Slice::ParamDecl::isOutParam() const
return _isOutParam;
}
+bool
+Slice::ParamDecl::optional() const
+{
+ return _optional;
+}
+
+int
+Slice::ParamDecl::tag() const
+{
+ return _tag;
+}
+
Contained::ContainedType
Slice::ParamDecl::containedType() const
{
@@ -5071,11 +5253,14 @@ Slice::ParamDecl::visit(ParserVisitor* visitor, bool)
visitor->visitParamDecl(this);
}
-Slice::ParamDecl::ParamDecl(const ContainerPtr& container, const string& name, const TypePtr& type, bool isOutParam) :
+Slice::ParamDecl::ParamDecl(const ContainerPtr& container, const string& name, const TypePtr& type, bool isOutParam,
+ bool optional, int tag) :
SyntaxTreeBase(container->unit()),
Contained(container, name),
_type(type),
- _isOutParam(isOutParam)
+ _isOutParam(isOutParam),
+ _optional(optional),
+ _tag(tag)
{
}
@@ -5089,6 +5274,18 @@ Slice::DataMember::type() const
return _type;
}
+bool
+Slice::DataMember::optional() const
+{
+ return _optional;
+}
+
+int
+Slice::DataMember::tag() const
+{
+ return _tag;
+}
+
string
Slice::DataMember::defaultValue() const
{
@@ -5138,11 +5335,13 @@ Slice::DataMember::visit(ParserVisitor* visitor, bool)
}
Slice::DataMember::DataMember(const ContainerPtr& container, const string& name, const TypePtr& type,
- const SyntaxTreeBasePtr& defaultValueType, const string& defaultValue,
- const string& defaultLiteral) :
+ bool optional, int tag, const SyntaxTreeBasePtr& defaultValueType,
+ const string& defaultValue, const string& defaultLiteral) :
SyntaxTreeBase(container->unit()),
Contained(container, name),
_type(type),
+ _optional(optional),
+ _tag(tag),
_defaultValueType(defaultValueType),
_defaultValue(defaultValue),
_defaultLiteral(defaultLiteral)