aboutsummaryrefslogtreecommitdiff
path: root/xsde/cxx/hybrid/serializer-source.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xsde/cxx/hybrid/serializer-source.cxx')
-rw-r--r--xsde/cxx/hybrid/serializer-source.cxx1001
1 files changed, 1001 insertions, 0 deletions
diff --git a/xsde/cxx/hybrid/serializer-source.cxx b/xsde/cxx/hybrid/serializer-source.cxx
new file mode 100644
index 0000000..37fff42
--- /dev/null
+++ b/xsde/cxx/hybrid/serializer-source.cxx
@@ -0,0 +1,1001 @@
+// file : xsde/cxx/hybrid/serializer-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/hybrid/serializer-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Hybrid
+ {
+ namespace
+ {
+ // Some built-in types are passed by pointer to built-in serializer
+ // implementations.
+ //
+ struct TypePass: Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::QName,
+ Traversal::Fundamental::IdRefs,
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+ Traversal::Fundamental::Entities,
+ Context
+ {
+ TypePass (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens&)
+ {
+ os << "&";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName&)
+ {
+ if (!stl)
+ os << "&";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs&)
+ {
+ os << "&";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary&)
+ {
+ os << "&";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary&)
+ {
+ os << "&";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities&)
+ {
+ os << "&";
+ }
+ };
+
+ //
+ //
+ struct List: Traversal::List, Context
+ {
+ List (Context& c)
+ : Context (c), type_pass_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String const& name (esimpl_custom (l));
+
+ if (!name)
+ return;
+
+ SemanticGraph::Type& t (l.argumented ().type ());
+
+ String const& skel (esskel (l));
+ String const& arg (sarg_type (l));
+ String const& ret (sret_type (t));
+
+ String item (unclash (skel, "item"));
+ String item_next (unclash (skel, "item_next"));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ String const& state (esstate (l));
+
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre (" << arg << " x)"
+ << "{"
+ << "this->" << state << ".i_ = x.begin ();"
+ << "this->" << state << ".end_ = x.end ();"
+ << "}";
+
+ // item_next
+ //
+ os << "bool " << name << "::" << endl
+ << item_next << " ()"
+ << "{"
+ << "return this->" << state << ".i_ != this->" <<
+ state << ".end_;"
+ << "}";
+
+ // item
+ //
+ os << ret << " " << name << "::" << endl
+ << item << " ()"
+ << "{"
+ << "return ";
+
+ type_pass_.dispatch (t);
+
+ os << "*this->" << state << ".i_++;"
+ << "}";
+ }
+
+ private:
+ TypePass type_pass_;
+ };
+
+ //
+ //
+ struct Union: Traversal::Union, Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String const& name (esimpl_custom (u));
+
+ if (!name)
+ return;
+
+ String const& state (esstate (u));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // pre
+ //
+ String const& arg (sarg_type (u));
+
+ os << "void " << name << "::" << endl
+ << "pre (" << arg << " x)"
+ << "{"
+ << "this->" << state << " = &x;"
+ << "}";
+
+ // _serialize_content
+ //
+ String const& value (u.context ().get<String> ("value"));
+
+ os << "void " << name << "::" << endl
+ << "_serialize_content ()"
+ << "{";
+
+ if (stl)
+ {
+ os << "const ::std::string& s = this->" << state << "->" <<
+ value << " ();"
+ << "this->_characters (s.c_str (), s.size ());";
+ }
+ else
+ os << "this->_characters (" <<
+ "this->" << state << "->" << value << " ());";
+
+ os << "}";
+ }
+ };
+
+ //
+ //
+ struct SerializerContext: Context
+ {
+ SerializerContext (Context& c)
+ : Context (c)
+ {
+ }
+
+ // Return the access sequence up until this particle. If
+ // element is false then the access sequence for the
+ // container is returned. Otherwise the access sequence
+ // for the current element in the container is returned.
+ //
+ String
+ access_seq (SemanticGraph::Particle& p, Boolean element = true)
+ {
+ using namespace SemanticGraph;
+
+ String r;
+
+ Boolean seq (false);
+
+ Compositor* c;
+
+ if (p.contained_particle_p ())
+ {
+ c = &p.contained_particle ().compositor ();
+
+ // Check if this particle is a sequence. In this case
+ // we just need the top-level struct member.
+ //
+ if (element && p.max () != 1)
+ {
+ seq = true;
+ }
+ else
+ {
+ for (;; c = &c->contained_particle ().compositor ())
+ {
+ if (c->context ().count ("type"))
+ {
+ // Not a see-through compositor.
+ //
+ if (c->max () != 1)
+ {
+ String const& iter (esstate_member (*c));
+
+ if (!r)
+ {
+ r = iter;
+ r += L"->";
+ }
+ else
+ {
+ String tmp;
+ tmp.swap (r);
+ r = iter;
+ r += L"->";
+ r += tmp;
+ }
+
+ seq = true;
+ break;
+ }
+ else
+ {
+ String const& func (ename (*c));
+
+ if (!r)
+ {
+ r = func;
+ r += L" ().";
+ }
+ else
+ {
+ String tmp;
+ tmp.swap (r);
+ r = func;
+ r += L" ().";
+ r += tmp;
+ }
+ }
+ }
+
+ if (c->contained_compositor_p ())
+ break;
+ }
+ }
+
+ // Get to the top in case we bailed out on a sequence.
+ //
+ while (!c->contained_compositor_p ())
+ c = &c->contained_particle ().compositor ();
+ }
+ else
+ {
+ // This particle is a top-level compositor.
+ //
+ c = &dynamic_cast<Compositor&> (p);
+ seq = element && c->max () != 1;
+ }
+
+ Complex& t (
+ dynamic_cast<Complex&> (
+ c->contained_compositor ().container ()));
+
+ if (!seq)
+ {
+ String const& s (esstate_member (t));
+
+ if (!r)
+ {
+ r = s;
+ r += L"->";
+ }
+ else
+ {
+ String tmp;
+ tmp.swap (r);
+ r = s;
+ r += L"->";
+ r += tmp;
+ }
+ }
+
+ String tmp;
+ tmp.swap (r);
+ r = esstate (t);
+ r += L".";
+ r += tmp;
+
+ return r;
+ }
+
+ String
+ access_seq (SemanticGraph::Attribute& a)
+ {
+ using namespace SemanticGraph;
+
+ Complex& t (dynamic_cast<Complex&> (a.scope ()));
+
+ String r (esstate (t));
+ r += L".";
+ r += esstate_member (t);
+ r += L"->";
+
+ return r;
+ }
+ };
+
+ //
+ // Test for presence of sequences.
+ //
+
+ struct CompositorTest: Traversal::Choice,
+ Traversal::Sequence
+ {
+ CompositorTest (Boolean& seq)
+ : seq_ (seq)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ if (c.max () != 1)
+ seq_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ if (s.max () != 1)
+ seq_ = true;
+ else if (s.min () == 1)
+ {
+ // Test nested particles of the see-through sequence.
+ //
+ Sequence::traverse (s);
+ }
+ }
+
+ private:
+ Boolean& seq_;
+ };
+
+ struct ParticleTest: Traversal::Element
+ {
+ ParticleTest (Boolean& seq)
+ : seq_ (seq)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (e.max () != 1)
+ seq_ = true;
+ }
+
+ private:
+ Boolean& seq_;
+ };
+
+ //
+ // State initializers.
+ //
+
+ struct CompositorInit: Traversal::Choice,
+ Traversal::Sequence,
+ SerializerContext
+ {
+ CompositorInit (Context& c)
+ : SerializerContext (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ if (c.max () != 1)
+ {
+ String access (access_seq (c));
+ String access_s (access_seq (c, false));
+ String const& iter (esstate_member (c));
+ String const& end (esstate_member_end (c));
+
+ // Initialize the iterator.
+ //
+ os << "this->" << access << end << " = this->" <<
+ access_s << ename (c) << " ().end ();"
+ << "this->" << access << iter << " = this->" <<
+ access << end << ";";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ if (s.max () != 1)
+ {
+ String access (access_seq (s));
+ String access_s (access_seq (s, false));
+ String const& iter (esstate_member (s));
+ String const& end (esstate_member_end (s));
+
+ // Initialize the iterator.
+ //
+ os << "this->" << access << end << " = this->" <<
+ access_s << ename (s) << " ().end ();"
+ << "this->" << access << iter << " = this->" <<
+ access << end << ";";
+ }
+ else if (s.min () == 1)
+ {
+ // Initialize nested particles of the see-through sequence.
+ //
+ Sequence::traverse (s);
+ }
+ }
+ };
+
+ struct ParticleInit: Traversal::Element, SerializerContext
+ {
+ ParticleInit (Context& c)
+ : SerializerContext (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (e.max () != 1)
+ {
+ String access (access_seq (e));
+ String access_s (access_seq (e, false));
+ String const& iter (esstate_member (e));
+ String const& end (esstate_member_end (e));
+ String const& name (ename (e));
+
+ // Initialize the iterator.
+ //
+ os << "this->" << access << iter << " = this->" <<
+ access_s << name << " ().begin ();"
+ << "this->" << access << end << " = this->" <<
+ access_s << name << " ().end ();";
+ }
+ }
+ };
+
+ //
+ // Callbacks.
+ //
+
+ struct CompositorCallback: Traversal::All,
+ Traversal::Choice,
+ Traversal::Sequence,
+ SerializerContext
+ {
+ CompositorCallback (Context& c, Traversal::ContainsParticle& init)
+ : SerializerContext (c),
+ init_ (init),
+ compositor_test_ (seq_),
+ particle_test_ (seq_)
+ {
+ compositor_test_ >> contains_particle_test_;
+ contains_particle_test_ >> compositor_test_;
+ contains_particle_test_ >> particle_test_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ // For the all compositor, maxOccurs=1 and minOccurs={0,1}.
+ //
+ if (a.min () == 0)
+ {
+ String const& s (esimpl_custom (scope (a)));
+
+ os << "bool " << s << "::" << endl
+ << espresent (a) << " ()"
+ << "{"
+ << "return this->" << access_seq (a) << epresent (a) << " ();"
+ << "}";
+ }
+
+ All::traverse (a);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ SemanticGraph::Complex& t (scope (c));
+
+ String access (access_seq (c));
+ String const& s (esimpl_custom (t));
+ String const& arm_tag (esarm_tag (c));
+
+ if (c.max () != 1)
+ {
+ String access_s (access_seq (c, false));
+ String const& iter (esstate_member (c));
+ String const& end (esstate_member_end (c));
+
+ // When iterating over a compositor sequence, there is no
+ // simple place to increment the iterator. So we will need
+ // to increment it in *_next() and make sure we handle the
+ // first call in a special way.
+ //
+ os << "bool " << s << "::" << endl
+ << esnext (c) << " ()"
+ << "{"
+ << "if (this->" << access << iter << " != this->" <<
+ access << end << ")" << endl
+ << "this->" << access << iter << "++;"
+ << "else" << endl
+ << "this->" << access << iter << " = this->" <<
+ access_s << ename (c) << " ().begin ();"
+ << endl
+ << "return this->" << access << iter << " != this->" <<
+ access << end << ";"
+ << "}";
+
+ os << esskel (t) << "::" << arm_tag << " " << s << "::" << endl
+ << esarm (c) << " ()"
+ << "{"
+ << arm_tag << " t (static_cast< " << arm_tag << " > (" << endl
+ << "this->" << access << iter << "->" << earm (c) << " ()));";
+ }
+ else if (c.min () == 0)
+ {
+ os << "bool " << s << "::" << endl
+ << espresent (c) << " ()"
+ << "{"
+ << "return this->" << access << epresent (c) << " ();"
+ << "}";
+
+ os << esskel (t) << "::" << arm_tag << " " << s << "::" << endl
+ << esarm (c) << " ()"
+ << "{"
+ << arm_tag << " t (static_cast< " << arm_tag << " > (" << endl
+ << "this->" << access << ename (c) << " ()." <<
+ earm (c) << " ()));";
+ }
+ else
+ {
+ os << esskel (t) << "::" << arm_tag << " " << s << "::" << endl
+ << esarm (c) << " ()"
+ << "{"
+ << arm_tag << " t (static_cast< " << arm_tag << " > (" << endl;
+
+
+ // We may be in a choice in which case we get a nested
+ // type (and accessor function) even for min == max == 1.
+ //
+ if (c.context ().count ("type"))
+ os << "this->" << access << ename (c) << " ()." <<
+ earm (c) << " ()));";
+ else
+ os << "this->" << access << earm (c) << " ()));";
+ }
+
+ // Test whether we have any arms that need initialization.
+ //
+ seq_ = false;
+
+ for (SemanticGraph::Choice::ContainsIterator
+ i (c.contains_begin ()), e (c.contains_end ());
+ !seq_ && i != e; ++i)
+ {
+ contains_particle_test_.dispatch (*i);
+ }
+
+ if (seq_)
+ {
+ os << "switch (t)"
+ << "{";
+
+ for (SemanticGraph::Choice::ContainsIterator
+ i (c.contains_begin ()), e (c.contains_end ());
+ i != e; ++i)
+ {
+ // Test if this arm needs initialization.
+ //
+ seq_ = false;
+ contains_particle_test_.dispatch (*i);
+
+ if (seq_)
+ {
+ SemanticGraph::Particle& p (i->particle ());
+
+ os << "case " << estag (p) << ":"
+ << "{";
+ init_.dispatch (*i);
+ os << "break;"
+ << "}";
+ }
+ }
+
+ os << "default:"
+ << "{"
+ << "break;"
+ << "}"
+ << "}";
+ }
+
+ os << "return t;"
+ << "}";
+
+ Choice::traverse (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ String const& sc (esimpl_custom (scope (s)));
+
+ if (s.max () != 1)
+ {
+ String access (access_seq (s));
+ String access_s (access_seq (s, false));
+ String const& iter (esstate_member (s));
+ String const& end (esstate_member_end (s));
+
+ // When iterating over a compositor sequence, there is no
+ // simple place to increment the iterator. So we will need
+ // to increment it in *_next() and make sure we handle the
+ // first call in a special way.
+ //
+ os << "bool " << sc << "::" << endl
+ << esnext (s) << " ()"
+ << "{"
+ << "if (this->" << access << iter << " != this->" <<
+ access << end << ")" << endl
+ << "this->" << access << iter << "++;"
+ << "else" << endl
+ << "this->" << access << iter << " = this->" <<
+ access_s << ename (s) << " ().begin ();"
+ << endl
+ << "if (this->" << access << iter << " != this->" <<
+ access << end << ")"
+ << "{";
+
+ Sequence::contains (s, init_);
+
+ os << "return true;"
+ << "}"
+ << "else" << endl
+ << "return false;"
+ << "}";
+ }
+ else if (s.min () == 0)
+ {
+ os << "bool " << sc << "::" << endl
+ << espresent (s) << " ()"
+ << "{"
+ << "if (this->" << access_seq (s) << epresent (s) << " ())"
+ << "{";
+
+ Sequence::contains (s, init_);
+
+ os << "return true;"
+ << "}"
+ << "else" << endl
+ << "return false;"
+ << "}";
+ }
+
+ Sequence::traverse (s);
+ }
+
+ private:
+ SemanticGraph::Complex&
+ scope (SemanticGraph::Compositor& c)
+ {
+ SemanticGraph::Compositor* root (&c);
+
+ while (root->contained_particle_p ())
+ root = &root->contained_particle ().compositor ();
+
+ return dynamic_cast<SemanticGraph::Complex&> (
+ root->contained_compositor ().container ());
+ }
+
+ private:
+ Traversal::ContainsParticle& init_;
+
+ Boolean seq_;
+ CompositorTest compositor_test_;
+ ParticleTest particle_test_;
+ Traversal::ContainsParticle contains_particle_test_;
+ };
+
+ struct ParticleCallback: Traversal::Element, SerializerContext
+ {
+ ParticleCallback (Context& c)
+ : SerializerContext (c), type_pass_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ String const& s (
+ esimpl_custom (
+ dynamic_cast<SemanticGraph::Complex&> (e.scope ())));
+
+ SemanticGraph::Type& t (e.type ());
+ String const& ret (sret_type (t));
+ String access (access_seq (e));
+
+ if (e.max () != 1)
+ {
+ String const& iter (esstate_member (e));
+
+ os << "bool " << s << "::" << endl
+ << esnext (e) << " ()"
+ << "{"
+ << "return this->" << access << iter << " != this->" <<
+ access << esstate_member_end (e) << ";"
+ << "}";
+
+ os << ret << " " << s << "::" << endl
+ << esname (e) << " ()"
+ << "{";
+
+ if (ret != L"void")
+ {
+ os << "return ";
+ type_pass_.dispatch (t);
+ os << "*this->" << access << iter << "++;";
+ }
+
+ os << "}";
+ }
+ else
+ {
+ if (e.min () == 0)
+ {
+ os << "bool " << s << "::" << endl
+ << espresent (e) << " ()"
+ << "{"
+ << "return this->" << access << epresent (e) << " ();"
+ << "}";
+ }
+
+ os << ret << " " << s << "::" << endl
+ << esname (e) << " ()"
+ << "{";
+
+ if (ret != L"void")
+ {
+ os << "return ";
+ type_pass_.dispatch (t);
+ os << "this->" << access << ename (e) << " ();";
+ }
+
+ os << "}";
+ }
+ }
+
+ private:
+ TypePass type_pass_;
+ };
+
+ struct AttributeCallback: Traversal::Attribute, SerializerContext
+ {
+ AttributeCallback (Context& c)
+ : SerializerContext (c), type_pass_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ String const& s (
+ esimpl_custom (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ String access (access_seq (a));
+
+ if (a.optional ())
+ {
+ os << "bool " << s << "::" << endl
+ << espresent (a) << " ()"
+ << "{"
+ << "return this->" << access << epresent (a) << " ();"
+ << "}";
+ }
+
+ SemanticGraph::Type& t (a.type ());
+ String const& ret (sret_type (t));
+
+ os << ret << " " << s << "::" << endl
+ << esname (a) << " ()"
+ << "{";
+
+ if (ret != L"void")
+ {
+ os << "return ";
+ type_pass_.dispatch (t);
+ os << "this->" << access << ename (a) << " ();";
+ }
+
+ os << "}";
+ }
+
+ private:
+ TypePass type_pass_;
+ };
+
+ //
+ //
+ struct Complex: Traversal::Complex, Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ type_pass_ (c),
+
+ // Initializers.
+ //
+ compositor_init_ (c),
+ particle_init_ (c),
+
+ // Callbacks.
+ //
+ compositor_callback_ (c, contains_particle_init_),
+ particle_callback_ (c),
+ attribute_callback_ (c)
+ {
+ // Initializers.
+ //
+ contains_compositor_init_ >> compositor_init_;
+ compositor_init_ >> contains_particle_init_;
+ contains_particle_init_ >> compositor_init_;
+ contains_particle_init_ >> particle_init_;
+
+ // Callbacks.
+ //
+ contains_compositor_callback_ >> compositor_callback_;
+ compositor_callback_ >> contains_particle_callback_;
+ contains_particle_callback_ >> compositor_callback_;
+ contains_particle_callback_ >> particle_callback_;
+
+ names_attribute_callback_ >> attribute_callback_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String const& name (esimpl_custom (c));
+
+ if (!name)
+ return;
+
+ Boolean hb (c.inherits_p ());
+ Boolean restriction (restriction_p (c));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // c-tor
+ //
+ if (tiein && hb)
+ os << name << "::" << endl
+ << name << " ()" << endl
+ << ": " << esskel (c) << " (&base_impl_)"
+ << "{"
+ << "}";
+
+ // pre
+ //
+ String const& arg (sarg_type (c));
+
+ os << "void " << name << "::" << endl
+ << "pre (" << arg << " x)"
+ << "{";
+
+ if (hb)
+ {
+ SemanticGraph::Type& b (c.inherits ().base ());
+
+ // Default serializer implementations for anyType and
+ // anySimpleType return void.
+ //
+ if (!b.is_a<SemanticGraph::AnyType> () &&
+ !b.is_a<SemanticGraph::AnySimpleType> ())
+ {
+
+ if (tiein)
+ os << "this->base_impl_.pre (";
+ else
+ os << esimpl (b) << "::pre (";
+
+ type_pass_.dispatch (b);
+
+ os << "x);";
+ }
+ }
+
+ if (!restriction)
+ {
+ os << "this->" << esstate (c) << "." << esstate_member (c) <<
+ " = &x;";
+
+ contains_compositor (c, contains_compositor_init_);
+ }
+
+ os << "}";
+
+ // Member callbacks.
+ //
+ if (!restriction)
+ {
+ names (c, names_attribute_callback_);
+ contains_compositor (c, contains_compositor_callback_);
+ }
+ }
+
+ private:
+ TypePass type_pass_;
+
+ // Initializers.
+ //
+ CompositorInit compositor_init_;
+ ParticleInit particle_init_;
+ Traversal::ContainsCompositor contains_compositor_init_;
+ Traversal::ContainsParticle contains_particle_init_;
+
+ // Callbacks.
+ //
+ CompositorCallback compositor_callback_;
+ ParticleCallback particle_callback_;
+ Traversal::ContainsCompositor contains_compositor_callback_;
+ Traversal::ContainsParticle contains_particle_callback_;
+
+ AttributeCallback attribute_callback_;
+ Traversal::Names names_attribute_callback_;
+ };
+ }
+
+ Void
+ generate_serializer_source (Context& ctx)
+ {
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}