final public Type Types() throws ParseException {
    Type type;
    Token type_t;
    Identifier identifier;
    Restriction restriction;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case SEQUENCE_OF_T:
      /* 'SEQUENCE OF' always comes with an identifier, stored in the restriction. */
              type_t = jj_consume_token(SEQUENCE_OF_T);
      identifier = TypeIdentifier();
          type = new TypeSequenceOf(identifier);
      break;
    case INTEGER_T:
    case UNSIGNED32_T:
    case UINTEGER32_T:
    case INTEGER32_T:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case INTEGER_T:
        type_t = jj_consume_token(INTEGER_T);
        break;
      case INTEGER32_T:
        type_t = jj_consume_token(INTEGER32_T);
        break;
      case UINTEGER32_T:
        type_t = jj_consume_token(UINTEGER32_T);
        break;
      case UNSIGNED32_T:
        type_t = jj_consume_token(UNSIGNED32_T);
        break;
      default:
        jj_la1[38] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
                   type = new TypeSmi(makeNodeToken(type_t));
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case LEFT_BRACE_T:
      case LEFT_PAREN_T:
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case LEFT_BRACE_T:
          restriction = RestrictionNamedNumberList();
          break;
        case LEFT_PAREN_T:
          restriction = RestrictionRange();
          break;
        default:
          jj_la1[39] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
              type.addRestriction(restriction);
        break;
      default:
        jj_la1[40] = jj_gen;
        ;
      }
      break;
    case GAUGE32_T:
    case GAUGE_T:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case GAUGE_T:
        type_t = jj_consume_token(GAUGE_T);
        break;
      case GAUGE32_T:
        type_t = jj_consume_token(GAUGE32_T);
        break;
      default:
        jj_la1[41] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
          type = new TypeSmi(makeNodeToken(type_t));
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case LEFT_PAREN_T:
        restriction = RestrictionRange();
              type.addRestriction(restriction);
        break;
      default:
        jj_la1[42] = jj_gen;
        ;
      }
      break;
    case BITS_T:
    case BIT_STRING_T:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case BITS_T:
        type_t = jj_consume_token(BITS_T);
        break;
      case BIT_STRING_T:
        type_t = jj_consume_token(BIT_STRING_T);
        break;
      default:
        jj_la1[43] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
          type = new TypeSmi(makeNodeToken(type_t));
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case LEFT_BRACE_T:
        restriction = RestrictionNamedNumberList();
              type.addRestriction(restriction);
        break;
      default:
        jj_la1[44] = jj_gen;
        ;
      }
      break;
    case OCTET_STRING_T:
    case OPAQUE_T:
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case OCTET_STRING_T:
        type_t = jj_consume_token(OCTET_STRING_T);
        break;
      case OPAQUE_T:
        type_t = jj_consume_token(OPAQUE_T);
        break;
      default:
        jj_la1[45] = jj_gen;
        jj_consume_token(-1);
        throw new ParseException();
      }
          type = new TypeSmi(makeNodeToken(type_t));
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case LEFT_PAREN_T:
        restriction = RestrictionSize(new Recovery(new int[0]));
              type.addRestriction(restriction);
        break;
      default:
        jj_la1[46] = jj_gen;
        ;
      }
      break;
    case OBJECT_IDENTIFIER_T:
      type_t = jj_consume_token(OBJECT_IDENTIFIER_T);
          type = new TypeSmi(makeNodeToken(type_t));
      break;
    case COUNTER_T:
      type_t = jj_consume_token(COUNTER_T);
          type = new TypeSmi(makeNodeToken(type_t));
      break;
    case COUNTER32_T:
      type_t = jj_consume_token(COUNTER32_T);
          type = new TypeSmi(makeNodeToken(type_t));
      break;
    case COUNTER64_T:
      type_t = jj_consume_token(COUNTER64_T);
          type = new TypeSmi(makeNodeToken(type_t));
      break;
    case TIMETICKS_T:
      type_t = jj_consume_token(TIMETICKS_T);
          type = new TypeSmi(makeNodeToken(type_t));
      break;
    case NSAP_ADDRESS_T:
      type_t = jj_consume_token(NSAP_ADDRESS_T);
          type = new TypeSmi(makeNodeToken(type_t));
      break;
    case IP_ADDRESS_T:
      type_t = jj_consume_token(IP_ADDRESS_T);
          type = new TypeSmi(makeNodeToken(type_t));
      break;
    case NETWORK_ADDRESS_T:
      type_t = jj_consume_token(NETWORK_ADDRESS_T);
          type = new TypeSmi(makeNodeToken(type_t));
      break;
    case TYPE_IDENTIFIER_T:
      identifier = TypeIdentifier();
          type = new TypeIdentifier(identifier);
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case LEFT_BRACE_T:
      case LEFT_PAREN_T:
        if (jj_2_8(2)) {
          restriction = RestrictionRange();
        } else {
          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
          case LEFT_BRACE_T:
            restriction = RestrictionNamedNumberList();
            break;
          default:
            jj_la1[47] = jj_gen;
            if (jj_2_9(2)) {
              restriction = RestrictionSize(new Recovery(new int[0]));
            } else {
              jj_consume_token(-1);
              throw new ParseException();
            }
          }
        }
              type.addRestriction(restriction);
        break;
      default:
        jj_la1[48] = jj_gen;
        ;
      }
      break;
    default:
      jj_la1[49] = jj_gen;
      jj_consume_token(-1);
      throw new ParseException();
    }
      {if (true) return type;}
    throw new Error("Missing return statement in function");
  }