-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AVRO-2397: Implement Alias Support for C++ #522
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ typedef std::shared_ptr<Node> NodePtr; | |
class AVRO_DECL Name { | ||
std::string ns_; | ||
std::string simpleName_; | ||
std::vector<std::string> aliases_; | ||
public: | ||
Name() { } | ||
Name(const std::string& fullname); | ||
|
@@ -52,6 +53,8 @@ public: | |
void ns(const std::string& n) { ns_ = n; } | ||
void simpleName(const std::string& n) { simpleName_ = n; } | ||
void fullname(const std::string& n); | ||
void addAlias(const std::string& alias); | ||
bool hasAlias(); | ||
|
||
bool operator < (const Name& n) const; | ||
void check() const; | ||
|
@@ -147,8 +150,8 @@ class AVRO_DECL Node : private boost::noncopyable | |
doAddName(name); | ||
} | ||
virtual size_t names() const = 0; | ||
virtual const std::string &nameAt(int index) const = 0; | ||
virtual bool nameIndex(const std::string &name, size_t &index) const = 0; | ||
virtual const Name &nameAt(int index) const = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change will break existing client code that assigns a |
||
virtual bool nameIndex(const Name &name, size_t &index) const = 0; | ||
|
||
void setFixedSize(int size) { | ||
checkLock(); | ||
|
@@ -187,7 +190,7 @@ class AVRO_DECL Node : private boost::noncopyable | |
virtual void doSetDoc(const std::string &name) = 0; | ||
|
||
virtual void doAddLeaf(const NodePtr &newLeaf) = 0; | ||
virtual void doAddName(const std::string &name) = 0; | ||
virtual void doAddName(const Name &name) = 0; | ||
virtual void doSetFixedSize(int size) = 0; | ||
|
||
private: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,6 +81,25 @@ static bool isFullName(const string &s) | |
return s.find('.') != string::npos; | ||
} | ||
|
||
static void addAliases(Name& nm, const Array * aliasesPtr) | ||
{ | ||
if (aliasesPtr) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We use K&R convention of having |
||
{ | ||
for (const Entity& item : *aliasesPtr) | ||
{ | ||
string itemVal = item.stringValue(); | ||
bool missingNs = nm.ns().empty(); | ||
if(missingNs || isFullName(itemVal)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a coding style we use |
||
nm.addAlias(itemVal); | ||
else | ||
{ | ||
itemVal += ("." + nm.ns()); | ||
nm.addAlias(itemVal); | ||
} | ||
} | ||
} | ||
} | ||
|
||
static Name getName(const string &name, const string &ns) | ||
{ | ||
return (isFullName(name)) ? Name(name) : Name(name, ns); | ||
|
@@ -166,10 +185,10 @@ const string getDocField(const Entity& e, const Object& m) | |
} | ||
|
||
struct Field { | ||
const string name; | ||
const Name name; | ||
const NodePtr schema; | ||
const GenericDatum defaultValue; | ||
Field(const string& n, const NodePtr& v, GenericDatum dv) : | ||
Field(const Name& n, const NodePtr& v, GenericDatum dv) : | ||
name(n), schema(v), defaultValue(dv) { } | ||
}; | ||
|
||
|
@@ -295,7 +314,17 @@ static GenericDatum makeGenericDatum(NodePtr n, | |
static Field makeField(const Entity& e, SymbolTable& st, const string& ns) | ||
{ | ||
const Object& m = e.objectValue(); | ||
const string& n = getStringField(e, m, "name"); | ||
Name n = getStringField(e, m, "name"); | ||
|
||
const Array *aliasesPtr = nullptr; | ||
|
||
if (containsField(m, "aliases")) | ||
{ | ||
const Array& aliases = getArrayField(e, m, "aliases"); | ||
for (const Entity& alias : aliases) | ||
n.addAlias(alias.stringValue()); | ||
} | ||
|
||
Object::const_iterator it = findField(e, m, "type"); | ||
map<string, Entity>::const_iterator it2 = m.find("default"); | ||
NodePtr node = makeNode(it->second, st, ns); | ||
|
@@ -312,7 +341,7 @@ static NodePtr makeRecordNode(const Entity& e, const Name& name, | |
const string* doc, const Object& m, | ||
SymbolTable& st, const string& ns) { | ||
const Array& v = getArrayField(e, m, "fields"); | ||
concepts::MultiAttribute<string> fieldNames; | ||
concepts::MultiAttribute<Name> fieldNames; | ||
concepts::MultiAttribute<NodePtr> fieldValues; | ||
vector<GenericDatum> defaultValues; | ||
|
||
|
@@ -375,7 +404,7 @@ static NodePtr makeEnumNode(const Entity& e, | |
const Name& name, const Object& m) | ||
{ | ||
const Array& v = getArrayField(e, m, "symbols"); | ||
concepts::MultiAttribute<string> symbols; | ||
concepts::MultiAttribute<Name> symbols; | ||
for (Array::const_iterator it = v.begin(); it != v.end(); ++it) { | ||
if (it->type() != json::etString) { | ||
throw Exception(boost::format("Enum symbol not a string: %1%") % | ||
|
@@ -434,9 +463,17 @@ static NodePtr makeMapNode(const Entity& e, const Object& m, | |
static Name getName(const Entity& e, const Object& m, const string& ns) | ||
{ | ||
const string& name = getStringField(e, m, "name"); | ||
const Array *aliasesPtr = nullptr; | ||
|
||
if (containsField(m, "aliases")) | ||
{ | ||
aliasesPtr = &getArrayField(e, m, "aliases"); | ||
} | ||
|
||
if (isFullName(name)) { | ||
return Name(name); | ||
Name nm(name); | ||
addAliases(nm, aliasesPtr); | ||
return nm; | ||
} else { | ||
Object::const_iterator it = m.find("namespace"); | ||
if (it != m.end()) { | ||
|
@@ -447,9 +484,12 @@ static Name getName(const Entity& e, const Object& m, const string& ns) | |
it->second.toString()); | ||
} | ||
Name result = Name(name, it->second.stringValue()); | ||
addAliases(result, aliasesPtr); | ||
return result; | ||
} | ||
return Name(name, ns); | ||
Name nm(name, ns); | ||
addAliases(nm, aliasesPtr); | ||
return nm; | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,6 +50,16 @@ void Name::fullname(const string& name) | |
check(); | ||
} | ||
|
||
void Name::addAlias(const std::string& alias) | ||
{ | ||
aliases_.emplace_back(alias); | ||
} | ||
|
||
bool Name::hasAlias() | ||
{ | ||
return aliases_.size() > 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think |
||
} | ||
|
||
bool Name::operator < (const Name& n) const | ||
{ | ||
return (ns_ < n.ns_) ? true : | ||
|
@@ -79,7 +89,30 @@ void Name::check() const | |
|
||
bool Name::operator == (const Name& n) const | ||
{ | ||
return ns_ == n.ns_ && simpleName_ == n.simpleName_; | ||
if (ns_ == n.ns_ && simpleName_ == n.simpleName_) | ||
return true; | ||
|
||
const std::string& myFullName = fullname(); | ||
const std::string& theirFullName = n.fullname(); | ||
|
||
for (const auto& theirAlias : n.aliases_) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have not used |
||
{ | ||
if (myFullName == theirAlias) | ||
return true; | ||
} | ||
|
||
for (const auto &myAlias : aliases_) | ||
{ | ||
if (myAlias == theirFullName) | ||
return true; | ||
for (const auto& theirAlias : n.aliases_) | ||
{ | ||
if (myAlias == theirAlias) | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
void Node::setLogicalType(LogicalType logicalType) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears that you editor inserts hard-tab instead of spaces. We use four spaces for indentation.