-- File [Ivy]<Nelson>Lupine>LupineMakeRpcModulesImpl.mesa.
-- Last edited by BZM on 11-May-82 16:25:46.


DIRECTORY
  CWF USING [WF2],
  LupineDeclare USING [
	BindingInterface, BindingRoutinesDynamic,
	BindingRoutinesPrivate, BindingRoutinesStandard,
	DispatcherHead, DispatcherSelect,
	DispatcherStubArm, DispatcherStubBody, DispatcherTail,
	Directory, DirectoryItem, ModuleHead, ProcedureIndex, ProcedureStub,
	SignalCatchStub, SignalCode, SignalIndex ],
  LupineMakeRpcModules USING [],
  LupineManagerPrivate USING [
	CloseCodeFile, Indent, Language, ModuleName, Nest,
	OpenCodeFile, Options, StampCodeFile, StampTranslationOptions,
	String, StringNIL, WFL1, WFS1, WFS, WFSL ],
  LupineMarshal USING [ParameterProtocolVersions],
  LupineSymbolTable USING [EnumerateTransfers, TransferProcedure];


LupineMakeRpcModulesImpl: PROGRAM
  IMPORTS
    CWF, Declare: LupineDeclare, LupineManagerPrivate, 
    Marshal: LupineMarshal, ST: LupineSymbolTable
  EXPORTS LupineMakeRpcModules =
  BEGIN OPEN LupineMakeRpcModules, LupineManagerPrivate;


MakeRpcControlModule: PUBLIC PROCEDURE [options: Options] =
  BEGIN
  controlModuleNames: ARRAY [0..1) OF String ← [ModuleName[control]];
  controlDirectoryList: ARRAY [0..2) OF Declare.DirectoryItem ← [
    [module: ModuleName[interface],
	openName: ModuleName[openedInterface],
	usedIn: [shares: TRUE, beginOpen: TRUE] ],
    [module: ModuleName[rpcPublic],
	usingAll: "defaultInterfaceName, EncryptionKey, InterfaceName, Principal, standardZones, VersionRange, Zones"L,
	openName: "RpcPublic"L,
	usedIn: [beginOpen: TRUE] ]  ];
	 
  oldest, newest: LONG INTEGER;
  [oldestSupported: oldest, newestSupported: newest]
    ← Marshal.ParameterProtocolVersions[];

  OpenCodeFile[ModuleName[control]];
  BEGIN ENABLE UNWIND => CloseCodeFile;
  StampCodeFile[ModuleName[control]];
  StampModuleNames;
  StampTranslationOptions[options];

  Declare.Directory [
	includeInterfaceDirectory: TRUE,
	extraDirectories: DESCRIPTOR[controlDirectoryList],
	options: options ];

  Declare.ModuleHead [
	moduleNames: DESCRIPTOR[controlModuleNames],
	moduleType: "DEFINITIONS"L,
	interfaceList: DESCRIPTOR[controlDirectoryList],
	options: options ];
  
  Declare.BindingInterface[options];

  WFS1["

-- Definitions for the stubs.

  LupineProtocolVersion: PUBLIC VersionRange = "L];
    CWF.WF2["[first: %LD, last: %LD]"L, @oldest, @newest];  WFS[";

  InterMdsCallsOnly: PUBLIC BOOLEAN = "L,
    (IF options.defaultParamPassing=InterMds THEN "TRUE"L ELSE "FALSE"L),
    ";*N"L];

  Declare.ProcedureIndex[];
  Declare.SignalIndex[];

  WFS["

    END.  -- "L, ModuleName[control], ".*N"L];

  END;  -- ENABLE UNWIND => CloseCodeFile.
  CloseCodeFile[];
  END;  -- MakeRpcControlModule.



MakeRpcClientModule: PUBLIC PROCEDURE [options: Options] =
  BEGIN
  clientModuleNames: ARRAY [0..1) OF String ← [ModuleName[client]];
  clientDirectoryList: ARRAY [0..13) OF Declare.DirectoryItem ← [
  --Common directory items:
    [module: ModuleName[interface],
	openName: ModuleName[openedInterface],
	usedIn: [exports: TRUE, shares: TRUE, beginOpen: TRUE] ],
    [module: ModuleName[control],
	openName: "RpcControl"L,
	usedIn: [exports: TRUE, shares: TRUE, beginOpen: TRUE],
	usingAll: "InterMdsCallsOnly, LupineProtocolVersion, ProcedureIndex, SignalIndex"L ],
    [module: ModuleName[rpcPublic],
	openName: "RpcPublic"L,
	usedIn: [beginOpen: TRUE],
	usingAll: "InterfaceName, standardZones, Zones"L ],
    [module: ModuleName[rpcPrivate],
	openName: "RpcPrivate"L,
	usedIn: [imports: TRUE],
	usingSome: "Call, DataLength, Dispatcher, GetStubPkt, ImportHandle, ImportInterface, maxDataLength, maxPrincipalLength, maxShortStringLength, pktOverhead, ReceiveExtraPkt, SendPrelimPkt, StartCall, StartSignal, StubPkt, UnimportInterface"L ],
    [module: ModuleName[lupineRuntime],
	openName: "Lupine"L,
	usedIn: [imports: TRUE],
	usingSome: "BindingError, CheckPktLength, CopyFromPkt, CopyFromMultiplePkts, CopyToPkt, CopyToMultiplePkts, DispatchingError, FinishThisPkt, ListHeader, MarshalingError, MarshalingExprError, NilHeader, ProtocolError, RopeHeader, RpcPktDoubleWord, RuntimeError, SequenceHeader, SHORT, StartNextPkt, StringHeader, StubPktDoubleWord, TranslationError, UnmarshalingError, UnmarshalingExprError, WordsForChars"L ],
  --Cedar directory items:
    [module: "Atom"L,
	usingSome: "GetPName, MakeAtom"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "ConvertUnsafe"L,
	usingAll: "AppendRope"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "Heap"L,
	usingAll: "systemMDSZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "Rope"L,
	usingSome: "Text"L,
	usedIn: [shares: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "RopeInline"L,
	usingSome: "InlineFlatten, NewText"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "SafeStorage"L,
	usingAll: "GetSystemZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "UnsafeStorage"L,
	usingAll: "GetSystemUZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
  --Mesa directory items:
    [module: "Heap"L,
	usingAll: "systemZone, systemMDSZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Mesa: TRUE] ]  ];

  OpenCodeFile[ModuleName[client]];
  BEGIN ENABLE UNWIND => CloseCodeFile;
  StampCodeFile[ModuleName[client]];
  StampModuleNames;
  StampTranslationOptions[options];

  Declare.Directory [
	includeInterfaceDirectory: TRUE,
	extraDirectories: DESCRIPTOR[clientDirectoryList],
	options: options ];

  Declare.ModuleHead [
	moduleNames: DESCRIPTOR[clientModuleNames],
	moduleType: "MONITOR"L,
	interfaceList: DESCRIPTOR[clientDirectoryList],
	options: options ];

  Declare.BindingRoutinesStandard[kind: import, options: options];

  WFS1["
*F
-- Remote public procedure stubs.*N"L];
  BEGIN
  DeclareInterfaceProcStub: ST.TransferProcedure =
    BEGIN
    Declare.ProcedureStub[ nest: 1,
	transfer: transfer,
	transferType: transferType,
	transferDeclaration: inInterface,
	signalDispatcherType: client,
	options: options  ];
    END;  -- DeclareInterfaceProcStub.
  [] ← ST.EnumerateTransfers[proc: DeclareInterfaceProcStub, procs: TRUE];
  END;  -- Remote public procedure stubs.

  WFS1["
*F
-- Remote public signals and errors.*N"L];
  BEGIN
  DeclareInterfaceSignal: ST.TransferProcedure =
    BEGIN
    Declare.SignalCode[ nest: 1,
	transfer: transfer,
	transferType: transferType,
	transferDeclaration: inInterface,
	options: options  ];
    END;  -- DeclareInterfaceSignal.
  [] ← ST.EnumerateTransfers[
	proc: DeclareInterfaceSignal, signals: TRUE, errors: TRUE ];
  END;  -- Remote public signals and errors.
    
  WFS1["

-- Public signal and error dispatcher.*N"L];
  Declare.DispatcherHead[type: client, nest: 1];
  WFS1["*N"L];
  Declare.DispatcherSelect[type: client, nest: 1];
  BEGIN
  DeclareDispatcherArm: ST.TransferProcedure =
    BEGIN
    Declare.DispatcherStubArm[ nest: 3,
	transfer: transfer,
	transferType: transferType,
	transferDeclaration: inInterface,
	options: options ];
    END;  -- DeclareDispatcherArm.
  [] ← ST.EnumerateTransfers[
	proc: DeclareDispatcherArm, signals:TRUE, errors:TRUE ];
  END;
  Declare.DispatcherTail[type: client, nest: 1];
    
  WFS1["

-- Public signal and error dispatcher stubs.*N"L];
  BEGIN
  DeclareDispatcherBody: ST.TransferProcedure =
    BEGIN
    Declare.DispatcherStubBody[ nest: 1,
	transfer: transfer,
	transferType: transferType,
	transferDeclaration: inInterface,
	inlineBody: TRUE,
	options: options ];
    END;  -- DeclareDispatcherBody.
  [] ← ST.EnumerateTransfers[
	proc: DeclareDispatcherBody, signals:TRUE, errors:TRUE ];
  END;

  WFS["

-- No module initialization.

  END.  -- "L, ModuleName[client], ".*N"L];

  END;  -- ENABLE UNWIND => CloseCodeFile.
  CloseCodeFile[];
  END;  -- MakeRpcClientModule.



MakeRpcClientBinderModule: PUBLIC PROCEDURE [options: Options] =
  BEGIN
  clientBinderModuleNames: ARRAY [0..1) OF String ← [ModuleName[clientBinder]];
  clientBinderDirectoryList: ARRAY [0..5) OF Declare.DirectoryItem ← [
  --Common directory items:
    [module: ModuleName[control],
	usingAll: "InterfaceRecord, InterfaceRecordObject"L,
	openName: "RpcControl"L,
	usedIn: [exports: TRUE, shares: TRUE, beginOpen: TRUE] ],
    [module: ModuleName[client],
	openName: "ClientPrototype"L,
	usedIn: [imports: TRUE] ],
    [module: ModuleName[rpcPublic],
	openName: "RpcPublic"L,
	usedIn: [beginOpen: TRUE],
	usingAll: "InterfaceName, Zones"L ],
  --Cedar directory items:
    [module: "RTTypesBasic"L,
	openName: "RTT"L,
	usingAll: "EstablishFinalization, FinalizationQueue, FQEmpty, FQNext, NewFQ"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
  --Mesa directory items:
    [module: "Heap"L,
	usingAll: "systemZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Mesa: TRUE] ]  ];

  OpenCodeFile[ModuleName[clientBinder]];
  BEGIN ENABLE UNWIND => CloseCodeFile;
  StampCodeFile[ModuleName[clientBinder]];
  StampModuleNames;
  StampTranslationOptions[options];

  WFS1["
-- NOTE: Discard this module unless you use dynamic client binding.*N"L];

  Declare.Directory [
	includeInterfaceDirectory: FALSE,
	extraDirectories: DESCRIPTOR[clientBinderDirectoryList],
	options: options ];

  Declare.ModuleHead [
	moduleNames: DESCRIPTOR[clientBinderModuleNames],
	moduleType: "MONITOR"L,
	interfaceList: DESCRIPTOR[clientBinderDirectoryList],
	options: options ];

  Declare.BindingRoutinesDynamic[kind: import, options: options];

  Declare.BindingRoutinesPrivate[kind: import, options: options];
  -- This includes module initialization code, and MUST be at the end.

  WFS["

  END.  -- "L, ModuleName[clientBinder], ".*N"L];

  END;  -- ENABLE UNWIND => CloseCodeFile.
  CloseCodeFile[];
  END;  -- MakeRpcClientBinderModule.



MakeRpcServerModule: PUBLIC PROCEDURE [options: Options] =
  BEGIN
  serverModuleNames: ARRAY [0..1) OF String ← [ModuleName[server]];
  serverDirectoryList: ARRAY [0..13) OF Declare.DirectoryItem ← [
  --Common directory items:
    [module: ModuleName[interface],
	openName: ModuleName[openedInterface],
	usedIn: [imports: TRUE, shares: TRUE, beginOpen: TRUE] ],
    [module: ModuleName[control],
	openName: "RpcControl"L,
	usedIn: [exports: TRUE, shares: TRUE, beginOpen: TRUE],
	usingAll: "InterMdsCallsOnly, LupineProtocolVersion, ProcedureIndex, SignalIndex"L ],
    [module: ModuleName[rpcPublic],
	openName: "RpcPublic"L,
	usedIn: [beginOpen: TRUE],
	usingAll: "EncryptionKey, InterfaceName, Principal, standardZones, Zones"L ],
    [module: ModuleName[rpcPrivate],
	openName: "RpcPrivate"L,
	usedIn: [imports: TRUE],
	usingSome: "Call, DataLength, Dispatcher, ExportHandle, ExportInterface, GetStubPkt, maxDataLength, maxPrincipalLength, maxShortStringLength, pktOverhead, ReceiveExtraPkt, SendPrelimPkt, StartCall, StartSignal, StubPkt, UnexportInterface"L ],
    [module: ModuleName[lupineRuntime],
	openName: "Lupine"L,
	usedIn: [imports: TRUE],
	usingSome: "BindingError, CheckPktLength, CopyFromPkt, CopyFromMultiplePkts, CopyToPkt, CopyToMultiplePkts, DispatchingError, FinishThisPkt, ListHeader, MarshalingError, MarshalingExprError, NilHeader, ProtocolError, RopeHeader, RpcPktDoubleWord, RuntimeError, SequenceHeader, SHORT, StartNextPkt, StringHeader, StubPktDoubleWord, TranslationError, UnmarshalingError, UnmarshalingExprError, WordsForChars"L ],
  --Cedar directory items:
    [module: "Atom"L,
	usingSome: "GetPName, MakeAtom"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "ConvertUnsafe"L,
	usingAll: "AppendRope"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "Heap"L,
	usingAll: "systemMDSZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "Rope"L,
	usingSome: "Text"L,
	usedIn: [shares: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "RopeInline"L,
	usingSome: "InlineFlatten, NewText"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "SafeStorage"L,
	usingAll: "GetSystemZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
    [module: "UnsafeStorage"L,
	usingAll: "GetSystemUZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Cedar: TRUE] ],
  --Mesa directory items:
    [module: "Heap"L,
	usingAll: "systemZone, systemMDSZone"L,
	usedIn: [imports: TRUE],
	forLanguage: [Mesa: TRUE] ]  ];

  OpenCodeFile[ModuleName[server]];
  BEGIN ENABLE UNWIND => CloseCodeFile;
  StampCodeFile[ModuleName[server]];
  StampModuleNames;
  StampTranslationOptions[options];

  Declare.Directory [
	includeInterfaceDirectory: TRUE,
	extraDirectories: DESCRIPTOR[serverDirectoryList],
	options: options ];

  Declare.ModuleHead [
	moduleNames: DESCRIPTOR[serverModuleNames],
	moduleType: "MONITOR"L,
	interfaceList: DESCRIPTOR[serverDirectoryList],
	options: options ];

  Declare.BindingRoutinesStandard [kind: export, options: options];

  WFS1["
*F
-- Public procedure dispatcher and public signal and error catcher.*N"L];
  Declare.DispatcherHead[type: server, nest: 1];
  WFS["*N"L, Indent[2], "-- Catch public signals.*N*N"L];
  WFL1[3, "ENABLE BEGIN"L];
  BEGIN
  DeclareSignalCatch: ST.TransferProcedure =
    BEGIN
    Declare.SignalCatchStub [ nest: 3,
	transfer: transfer,
	transferType: transferType,
	transferDeclaration: inInterface,
	options: options ];
    END;  -- DeclareSignalCatch.
  [] ← ST.EnumerateTransfers[
	proc: DeclareSignalCatch, signals: TRUE, errors: TRUE ];
  END;
  WFS["*N"L, Indent[3], "END;  -- Catch public signals.*N"L];

  WFS["*N*N"L, Indent[2],
    "-- Call public procedures (still in dispatcher).*N*N"L];
  Declare.DispatcherSelect[type: server, nest: 1];
  BEGIN
  DeclareDispatcherArm: ST.TransferProcedure =
    BEGIN
    Declare.DispatcherStubArm[ nest: 3,
	transfer: transfer,
	transferType: transferType,
	transferDeclaration: inInterface,
	options: options ];
    END;  -- DeclareDispatcherArm.
  [] ← ST.EnumerateTransfers[proc: DeclareDispatcherArm, procs: TRUE];
  END;
  Declare.DispatcherTail[type: server, nest: 1];
    
  WFS1["

-- Public procedure dispatcher stubs.*N"L];
  BEGIN
  DeclareDispatcherBody: ST.TransferProcedure =
    BEGIN
    Declare.DispatcherStubBody[ nest: 1,
	transfer: transfer,
	transferType: transferType,
	transferDeclaration: inInterface,
	inlineBody: options.inlineServerDispatcherStubs,
	options: options ];
    END;  -- DeclareDispatcherBody.
  [] ← ST.EnumerateTransfers[proc: DeclareDispatcherBody, procs: TRUE];
  END;

  WFS["

-- No module initialization.

  END.  -- "L, ModuleName[server], ".*N"L];

  END;  -- ENABLE UNWIND => CloseCodeFile.
  CloseCodeFile[];
  END;  -- MakeRpcServerModule.



-- Private utility routines.

StampModuleNames: PROCEDURE =
  BEGIN
  WFSL["
-- The RPC stub modules for "L, ModuleName[interface], " are:
    -- "L, ModuleName[control], ".mesa;
    -- "L, ModuleName[client], ".mesa;
    -- "L, ModuleName[clientBinder], ".mesa;
    -- "L, ModuleName[server], ".mesa.*N"L];
  END;  -- StampModuleNames.


END.  -- LupineMakeRpcModulesImpl.