# extensions
extension_default = EXTENSIBILITY_IMPLIED | empty
- # types
- defined_type = Unique(typereference) # todo: consider other defined types from 13.1
- referenced_type = Unique(defined_type) # todo: consider other ref:d types from 16.3
-
# Forward-declare these, they can only be fully defined once
# we have all types defined. There are some circular dependencies.
named_type = Forward()
characterstring_type = restricted_characterstring_type | unrestricted_characterstring_type
# todo: consider other builtins from 16.2
- simple_type = (boolean_type | null_type | octetstring_type | characterstring_type | real_type | plain_integer_type | object_identifier_type) + Optional(constraint)
- constructed_type = choice_type | sequence_type | set_type
+ defined_type = Unique(typereference) # todo: consider other defined types from 13.1
+
+ # these productions are used for custom parse actions,
+ # because they typically generate similar code.
+ simple_type = (boolean_type | null_type | octetstring_type | characterstring_type | real_type | plain_integer_type | object_identifier_type) # + Optional(constraint)
value_list_type = restricted_integer_type | enumerated_type
- builtin_type = tagged_type | simple_type | constructed_type | sequenceof_type | setof_type | value_list_type | bitstring_type
- type_ << (builtin_type | referenced_type)
+ builtin_type = tagged_type | simple_type | choice_type | sequence_type | set_type | sequenceof_type | setof_type | value_list_type | bitstring_type
+ referenced_type = Unique(defined_type) # todo: consider other ref:d types from 16.3
+
+ type_ << ((builtin_type | referenced_type) + Optional(constraint))
# BUG: identifier should not be Optional here,
# but our ASN.1 interpreter supports unnamed members,
SequenceOfType: self.decl_sequenceof_type,
SetOfType: self.decl_setof_type,
TypeAssignment: self.decl_type_assignment,
- ValueAssignment: self.decl_value_assignment
+ ValueAssignment: self.decl_value_assignment,
+ Type: self.decl_type,
}
self.expr_generators = {
ChoiceType: self.expr_constructed_type,
SequenceType: self.expr_constructed_type,
SetType: self.expr_constructed_type,
+ Type: self.expr_type,
}
def generate_code(self):
fragment.write_line('class %s(%s):' % (assigned_type, base_type))
fragment.push_indent()
- fragment.write_block(self.generate_decl(type_decl))
+ fragment.write_block(self.generate_decl(type_decl) or 'pass')
fragment.pop_indent()
return str(fragment)
- def expr_simple_type(self, t):
- type_expr = _translate_type(t.type_name) + '()'
+ def expr_type(self, t):
+ type_expr = self.generate_expr(t.type_decl)
if t.constraint:
type_expr += '.subtype(subtypeSpec=constraint.ValueRangeConstraint(%s, %s))' % (t.constraint.min_value, t.constraint.max_value)
return type_expr
- def decl_simple_type(self, t):
+ def decl_type(self, t):
+ type_decl = self.generate_decl(t.type_decl)
if t.constraint:
- return 'subtypeSpec = constraint.ValueRangeConstraint(%s, %s)' % (t.constraint.min_value, t.constraint.max_value)
- else:
- return 'pass'
+ type_decl += 'subtypeSpec = constraint.ValueRangeConstraint(%s, %s)' % (t.constraint.min_value, t.constraint.max_value)
+
+ return type_decl
+
+ def expr_simple_type(self, t):
+ return _translate_type(t.type_name) + '()'
+
+ def decl_simple_type(self, t):
+ return ''
def expr_userdefined_type(self, t):
return t.type_name + '()'
def decl_userdefined_type(self, t):
- return 'pass'
+ return ''
def decl_constructed_type(self, t):
fragment = self.writer.get_fragment()
tag_type = 'tagImplicitly' if t.implicit else 'tagExplicitly'
base_type = _translate_type(t.type_decl.type_name)
fragment.write_line('tagSet = %s.tagSet.%s(%s)' % (base_type, tag_type, self.build_tag_expr(t)))
- fragment.write_line(self.generate_decl(t.type_decl)) # possibly 'pass'. but that's OK in a decl
+ fragment.write_line(self.generate_decl(t.type_decl))
return str(fragment)
fragment.pop_indent()
fragment.write_line(')')
- else:
- fragment.write_line('pass')
return str(fragment)
fragment.pop_indent()
fragment.write_line(')')
- else:
- fragment.write_line('pass')
return str(fragment)
print('WARNING: More than one module generated to the same stream.', file=sys.stderr)
for module in modules:
- print(pygen.auto_generated_header())
+ print(pygen.auto_generated_header(args[0]))
generate_pyasn1(module, sys.stdout)
return 0
"""
user_types = self.user_types()
+ # Drill through Type, it acts as a container
+ # for type + metadata like constraints.
+ if isinstance(type_decl, Type):
+ type_decl = type_decl.type_decl
+
if isinstance(type_decl, UserDefinedType):
return self.resolve_type_decl(user_types[type_decl.type_name])
else:
__repr__ = __str__
+class Type(object):
+ def __init__(self, elements):
+ self.type_decl = _create_sema_node(elements[0])
+ if len(elements) == 2:
+ assert elements[1].ty == 'Constraint'
+ self.constraint = Constraint(elements[1].elements)
+ else:
+ self.constraint = None
+
+ @property
+ def type_name(self):
+ return self.type_decl.type_name
+
+ def reference_name(self):
+ return self.type_decl.type_name
+
+ def references(self):
+ if self.constraint:
+ return self.constraint.references()
+
+ return []
+
+ def __str__(self):
+ if self.constraint:
+ return '%s %s' % (self.type_decl, self.constraint)
+ else:
+ return str(self.type_decl)
+
+ __repr__ = __str__
+
+
class ConstructedType(object):
""" Base type for SEQUENCE, SET and CHOICE. """
def __init__(self, elements):
elif token.ty == 'NamedValue':
return NamedValue(token.elements)
elif token.ty == 'Type':
- # Type tokens have a more specific type category
- # embedded as their first element
- return _create_sema_node(token.elements[0])
+ return Type(token.elements)
elif token.ty == 'SimpleType':
return SimpleType(token.elements)
elif token.ty == 'ReferencedType':
--- /dev/null
+TEST DEFINITIONS ::=
+BEGIN
+ UnsignedInt ::= INTEGER (0..4294967295)
+
+ intMax INTEGER ::= 4294967295
+ UnsignedIntAgain ::= INTEGER (0..intMax)
+
+-- PkcsTricky ::= INTEGER {v3(3)}(v3,...)
+
+ Seq ::= SEQUENCE {
+ valueConstrained INTEGER (0..4294967295),
+ taggedValueConstrained [1] INTEGER (0..4294967295),
+ definedValueConstrained INTEGER (0..intMax)
+-- inlineBracedListAndConstraint INTEGER {v3(3)}(v3,...)
+ }
+
+ ConstrainedList ::= SEQUENCE OF INTEGER (1..64)
+
+ Bob ::= UnsignedInt (10..20)
+
+END