1 // Copyright 2016 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H
16 #define GRPC_SRC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <string>
21 #include <vector>
22 
23 #include "absl/status/statusor.h"
24 #include "absl/strings/string_view.h"
25 
26 #include <grpc/support/log.h>
27 
28 #include "src/core/lib/channel/channel_args.h"
29 #include "src/core/lib/channel/channel_fwd.h"
30 #include "src/core/lib/gprpp/ref_counted_ptr.h"
31 #include "src/core/lib/surface/channel_stack_type.h"
32 #include "src/core/lib/transport/transport_fwd.h"
33 
34 namespace grpc_core {
35 
36 // Build a channel stack.
37 // Allows interested parties to add filters to the stack, and to query an
38 // in-progress build.
39 // Carries some useful context for the channel stack, such as a target string
40 // and a transport.
41 class ChannelStackBuilder {
42  public:
43   // Initialize with a name.
44   // channel_args *must be* preconditioned already.
45   ChannelStackBuilder(const char* name, grpc_channel_stack_type type,
46                       const ChannelArgs& channel_args);
47 
name()48   const char* name() const { return name_; }
49 
50   // Set the target string.
51   ChannelStackBuilder& SetTarget(const char* target);
52 
53   // Query the target.
target()54   absl::string_view target() const { return target_; }
55 
56   // Set the transport.
SetTransport(grpc_transport * transport)57   ChannelStackBuilder& SetTransport(grpc_transport* transport) {
58     GPR_ASSERT(transport_ == nullptr);
59     transport_ = transport;
60     return *this;
61   }
62 
63   // Query the transport.
transport()64   grpc_transport* transport() const { return transport_; }
65 
66   // Query the channel args.
channel_args()67   const ChannelArgs& channel_args() const { return args_; }
68 
69   // Mutable vector of proposed stack entries.
mutable_stack()70   std::vector<const grpc_channel_filter*>* mutable_stack() { return &stack_; }
71 
72   // Immutable vector of proposed stack entries.
stack()73   const std::vector<const grpc_channel_filter*>& stack() const {
74     return stack_;
75   }
76 
77   // The type of channel stack being built.
channel_stack_type()78   grpc_channel_stack_type channel_stack_type() const { return type_; }
79 
80   // Helper to add a filter to the front of the stack.
81   void PrependFilter(const grpc_channel_filter* filter);
82 
83   // Helper to add a filter to the end of the stack.
84   void AppendFilter(const grpc_channel_filter* filter);
85 
86   // Determine whether a promise-based call stack is able to be built.
87   // Iterates each filter and ensures that there's a promise factory there.
88   // This will go away once the promise conversion is completed.
89   virtual bool IsPromising() const = 0;
90 
91   // Build the channel stack.
92   // After success, *result holds the new channel stack,
93   // prefix_bytes are allocated before the channel stack,
94   // destroy is as per grpc_channel_stack_init
95   // On failure, *result is nullptr.
96   virtual absl::StatusOr<RefCountedPtr<grpc_channel_stack>> Build() = 0;
97 
98  protected:
99   ~ChannelStackBuilder() = default;
100 
101  private:
unknown_target()102   static std::string unknown_target() { return "unknown"; }
103 
104   // The name of the stack
105   const char* const name_;
106   // The type of stack being built
107   const grpc_channel_stack_type type_;
108   // The target
109   std::string target_{unknown_target()};
110   // The transport
111   grpc_transport* transport_ = nullptr;
112   // Channel args
113   ChannelArgs args_;
114   // The in-progress stack
115   std::vector<const grpc_channel_filter*> stack_;
116 };
117 
118 }  // namespace grpc_core
119 
120 #endif  // GRPC_SRC_CORE_LIB_CHANNEL_CHANNEL_STACK_BUILDER_H
121