private Node buildFieldDecl(FieldDecl fd) throws SemanticException {
    Type t = fd.declType();

    if (t.isSubtype(SJ_PROTOCOL_TYPE)) {
      if (!(fd instanceof SJFieldProtocolDecl)) {
        throw new SemanticException(
            "[SJProtocolDeclTypeBuilder] Protocols may only be declared using the protocol keyword: "
                + fd);
      }

      SJTypeNode tn = disambiguateSJTypeNode(this, ((SJProtocolDecl) fd).sessionType());
      SJSessionType st = tn.type();
      String sjname = fd.name(); // Should match that given by SJVariable.sjname.

      SJFieldInstance fi = (SJFieldInstance) fd.fieldInstance();
      SJFieldProtocolInstance fpi =
          sjts.SJFieldProtocolInstance((SJFieldInstance) fd.fieldInstance(), st, sjname);

      fpi.setConstantValue(
          fi
              .constantValue()); // Currently, constant checker not run on custom nodes/type
                                 // objects. (Previously done by SJNoAliasTypeBuilder.)

      fd = fd.fieldInstance(fpi);
      fd = (FieldDecl) setSJProtocolDeclExt((SJProtocolDecl) fd, tn, sjname);

      updateSJFieldInstance(fi, fpi);
    }

    return fd;
  }
  private Node buildFormal(Formal f) throws SemanticException // Based on buildLocalDecl.
      {
    Type t = f.declType();
    SJLocalInstance li = (SJLocalInstance) f.localInstance();

    if (t.isSubtype(SJ_ABSTRACT_CHANNEL_TYPE)) {
      if (!(f instanceof SJFormal)) {
        throw new SemanticException(
            "[SJProtocolDeclTypeBuilder] Session socket parameters should be declared by their session type: "
                + f);
      }

      SJTypeNode tn = disambiguateSJTypeNode(this, ((SJFormal) f).sessionType());
      SJSessionType st = tn.type();
      String sjname = f.name(); // Should match that given by SJVariable.sjname.

      f = f.localInstance(sjts.SJLocalProtocolInstance(li, st, sjname));
      f = setSJFormalExt((SJFormal) f, tn, sjname);
    }

    return f;
  }
  private Node buildLocalDecl(LocalDecl ld) throws SemanticException {
    Type t = ld.declType();
    SJLocalInstance li = (SJLocalInstance) ld.localInstance();
    // SJNamedInstance ni = null;

    if (t.isSubtype(SJ_PROTOCOL_TYPE)) // Mostly the same as for LocalDecl.
    {
      if (!(ld instanceof SJLocalProtocolDecl)) {
        throw new SemanticException(
            "[SJProtocolDeclTypeBuilder] Protocols may only be declared using the protocol keyword: "
                + ld);
      }

      SJTypeNode tn = disambiguateSJTypeNode(this, ((SJProtocolDecl) ld).sessionType());
      SJSessionType st = tn.type();
      String sjname = ld.name(); // Should match that given by SJVariable.sjname.

      ld = ld.localInstance(sjts.SJLocalProtocolInstance(li, st, sjname));
      ld = (LocalDecl) setSJProtocolDeclExt((SJProtocolDecl) ld, tn, sjname);
    }

    return ld;
  }