@@ -473,3 +473,289 @@ extension ExtensionDescription {
473
473
)
474
474
}
475
475
}
476
+
477
+ extension FunctionSignatureDescription {
478
+ /// ```
479
+ /// func <Name>(
480
+ /// request: <Input>,
481
+ /// context: GRPCCore.ServerContext,
482
+ /// ) async throws -> <Output>
483
+ /// ```
484
+ ///
485
+ /// ```
486
+ /// func <Name>(
487
+ /// request: GRPCCore.RPCAsyncSequence<Input, any Error>,
488
+ /// response: GRPCCore.RPCAsyncWriter<Output>
489
+ /// context: GRPCCore.ServerContext,
490
+ /// ) async throws
491
+ /// ```
492
+ static func simpleServerMethod(
493
+ accessLevel: AccessModifier ? = nil ,
494
+ name: String ,
495
+ input: String ,
496
+ output: String ,
497
+ streamingInput: Bool ,
498
+ streamingOutput: Bool
499
+ ) -> Self {
500
+ var parameters : [ ParameterDescription ] = [
501
+ ParameterDescription (
502
+ label: " request " ,
503
+ type: streamingInput ? . rpcAsyncSequence( forType: input) : . member( input)
504
+ )
505
+ ]
506
+
507
+ if streamingOutput {
508
+ parameters. append ( ParameterDescription ( label: " response " , type: . rpcWriter( forType: output) ) )
509
+ }
510
+
511
+ parameters. append ( ParameterDescription ( label: " context " , type: . serverContext) )
512
+
513
+ return FunctionSignatureDescription (
514
+ accessModifier: accessLevel,
515
+ kind: . function( name: name) ,
516
+ parameters: parameters,
517
+ keywords: [ . async, . throws] ,
518
+ returnType: streamingOutput ? nil : . identifier( . pattern( output) )
519
+ )
520
+ }
521
+ }
522
+
523
+ extension ProtocolDescription {
524
+ /// ```
525
+ /// protocol SimpleServiceProtocol: <ServiceProtocol> {
526
+ /// ...
527
+ /// }
528
+ /// ```
529
+ static func simpleServiceProtocol(
530
+ accessModifier: AccessModifier ? = nil ,
531
+ name: String ,
532
+ serviceProtocol: String ,
533
+ methods: [ MethodDescriptor ]
534
+ ) -> Self {
535
+ func docs( for method: MethodDescriptor ) -> String {
536
+ let summary = """
537
+ /// Handle the " \( method. name. normalizedBase) " method.
538
+ """
539
+
540
+ let requestText =
541
+ method. isInputStreaming
542
+ ? " A stream of ` \( method. inputType) ` messages. "
543
+ : " A ` \( method. inputType) ` message. "
544
+
545
+ var parameters = """
546
+ /// - Parameters:
547
+ /// - request: \( requestText)
548
+ """
549
+
550
+ if method. isOutputStreaming {
551
+ parameters += " \n "
552
+ parameters += """
553
+ /// - response: A response stream of ` \( method. outputType) ` messages.
554
+ """
555
+ }
556
+
557
+ parameters += " \n "
558
+ parameters += """
559
+ /// - context: Context providing information about the RPC.
560
+ /// - Throws: Any error which occurred during the processing of the request. Thrown errors
561
+ /// of type `RPCError` are mapped to appropriate statuses. All other errors are converted
562
+ /// to an internal error.
563
+ """
564
+
565
+ if !method. isOutputStreaming {
566
+ parameters += " \n "
567
+ parameters += """
568
+ /// - Returns: A ` \( method. outputType) ` to respond with.
569
+ """
570
+ }
571
+
572
+ return Docs . interposeDocs ( method. documentation, between: summary, and: parameters)
573
+ }
574
+
575
+ return ProtocolDescription (
576
+ accessModifier: accessModifier,
577
+ name: name,
578
+ conformances: [ serviceProtocol] ,
579
+ members: methods. map { method in
580
+ . commentable(
581
+ . preFormatted( docs ( for: method) ) ,
582
+ . function(
583
+ signature: . simpleServerMethod(
584
+ name: method. name. generatedLowerCase,
585
+ input: method. inputType,
586
+ output: method. outputType,
587
+ streamingInput: method. isInputStreaming,
588
+ streamingOutput: method. isOutputStreaming
589
+ )
590
+ )
591
+ )
592
+ }
593
+ )
594
+ }
595
+ }
596
+
597
+ extension FunctionCallDescription {
598
+ /// ```
599
+ /// try await self.<Name>(
600
+ /// request: request.message,
601
+ /// response: writer,
602
+ /// context: context
603
+ /// )
604
+ /// ```
605
+ static func serviceMethodCallingSimpleMethod(
606
+ name: String ,
607
+ input: String ,
608
+ output: String ,
609
+ streamingInput: Bool ,
610
+ streamingOutput: Bool
611
+ ) -> Self {
612
+ var arguments : [ FunctionArgumentDescription ] = [
613
+ FunctionArgumentDescription (
614
+ label: " request " ,
615
+ expression: . identifierPattern( " request " ) . dot ( streamingInput ? " messages " : " message " )
616
+ )
617
+ ]
618
+
619
+ if streamingOutput {
620
+ arguments. append (
621
+ FunctionArgumentDescription (
622
+ label: " response " ,
623
+ expression: . identifierPattern( " writer " )
624
+ )
625
+ )
626
+ }
627
+
628
+ arguments. append (
629
+ FunctionArgumentDescription (
630
+ label: " context " ,
631
+ expression: . identifierPattern( " context " )
632
+ )
633
+ )
634
+
635
+ return FunctionCallDescription (
636
+ calledExpression: . try ( . await ( . identifierPattern( " self " ) . dot ( name) ) ) ,
637
+ arguments: arguments
638
+ )
639
+ }
640
+ }
641
+
642
+ extension FunctionDescription {
643
+ /// ```
644
+ /// func <Name>(
645
+ /// request: GRPCCore.ServerRequest<Input>,
646
+ /// context: GRPCCore.ServerContext
647
+ /// ) async throws -> GRPCCore.ServerResponse<Output> {
648
+ /// return GRPCCore.ServerResponse<Output>(
649
+ /// message: try await self.<Name>(
650
+ /// request: request.message,
651
+ /// context: context
652
+ /// )
653
+ /// metadata: [:]
654
+ /// )
655
+ /// }
656
+ /// ```
657
+ static func serviceProtocolDefaultImplementation(
658
+ accessModifier: AccessModifier ? = nil ,
659
+ name: String ,
660
+ input: String ,
661
+ output: String ,
662
+ streamingInput: Bool ,
663
+ streamingOutput: Bool
664
+ ) -> Self {
665
+ func makeUnaryOutputArguments( ) -> [ FunctionArgumentDescription ] {
666
+ return [
667
+ FunctionArgumentDescription (
668
+ label: " message " ,
669
+ expression: . functionCall(
670
+ . serviceMethodCallingSimpleMethod(
671
+ name: name,
672
+ input: input,
673
+ output: output,
674
+ streamingInput: streamingInput,
675
+ streamingOutput: streamingOutput
676
+ )
677
+ )
678
+ ) ,
679
+ FunctionArgumentDescription ( label: " metadata " , expression: . literal( . dictionary( [ ] ) ) ) ,
680
+ ]
681
+ }
682
+
683
+ func makeStreamingOutputArguments( ) -> [ FunctionArgumentDescription ] {
684
+ return [
685
+ FunctionArgumentDescription ( label: " metadata " , expression: . literal( . dictionary( [ ] ) ) ) ,
686
+ FunctionArgumentDescription (
687
+ label: " producer " ,
688
+ expression: . closureInvocation(
689
+ argumentNames: [ " writer " ] ,
690
+ body: [
691
+ . expression(
692
+ . functionCall(
693
+ . serviceMethodCallingSimpleMethod(
694
+ name: name,
695
+ input: input,
696
+ output: output,
697
+ streamingInput: streamingInput,
698
+ streamingOutput: streamingOutput
699
+ )
700
+ )
701
+ ) ,
702
+ . expression( . return( . literal( . dictionary( [ ] ) ) ) ) ,
703
+ ]
704
+ )
705
+ ) ,
706
+ ]
707
+ }
708
+
709
+ return FunctionDescription (
710
+ signature: . serverMethod(
711
+ accessLevel: accessModifier,
712
+ name: name,
713
+ input: input,
714
+ output: output,
715
+ streamingInput: streamingInput,
716
+ streamingOutput: streamingOutput
717
+ ) ,
718
+ body: [
719
+ . expression(
720
+ . functionCall(
721
+ calledExpression: . return(
722
+ . identifierType(
723
+ . serverResponse( forType: output, streaming: streamingOutput)
724
+ )
725
+ ) ,
726
+ arguments: streamingOutput ? makeStreamingOutputArguments ( ) : makeUnaryOutputArguments ( )
727
+ )
728
+ )
729
+ ]
730
+ )
731
+ }
732
+ }
733
+
734
+ extension ExtensionDescription {
735
+ /// ```
736
+ /// extension ServiceProtocol {
737
+ /// ...
738
+ /// }
739
+ /// ```
740
+ static func serviceProtocolDefaultImplementation(
741
+ accessModifier: AccessModifier ? = nil ,
742
+ on extensionName: String ,
743
+ methods: [ MethodDescriptor ]
744
+ ) -> Self {
745
+ ExtensionDescription (
746
+ onType: extensionName,
747
+ declarations: methods. map { method in
748
+ . function(
749
+ . serviceProtocolDefaultImplementation(
750
+ accessModifier: accessModifier,
751
+ name: method. name. generatedLowerCase,
752
+ input: method. inputType,
753
+ output: method. outputType,
754
+ streamingInput: method. isInputStreaming,
755
+ streamingOutput: method. isOutputStreaming
756
+ )
757
+ )
758
+ }
759
+ )
760
+ }
761
+ }
0 commit comments