| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package codegen |
| |
| const fragmentProtocolTmpl = ` |
| {{- define "ProtocolForwardDeclaration" }} |
| {{ EnsureNamespace . }} |
| class {{ .Name }}; |
| {{- end }} |
| |
| {{- define "ForwardMessageParamsUnwrapTypedChannels" -}} |
| {{- range $index, $param := . -}} |
| {{- if $index }}, {{ end -}} std::move( |
| {{- if or (eq .Type.Kind TypeKinds.Protocol) (eq .Type.Kind TypeKinds.Request) -}} |
| {{ $param.Name }}.channel() |
| {{- else -}} |
| {{ $param.Name }} |
| {{- end -}} |
| ) |
| {{- end -}} |
| {{- end }} |
| |
| |
| {{- define "ClientAllocationComment" -}} |
| {{- if SyncCallTotalStackSize . }} Allocates {{ SyncCallTotalStackSize . }} bytes of {{ "" }} |
| {{- if not .Request.ClientAllocation.IsStack -}} response {{- else -}} |
| {{- if not .Response.ClientAllocation.IsStack -}} request {{- else -}} message {{- end -}} |
| {{- end }} buffer on the stack. {{- end }} |
| {{- if and .Request.ClientAllocation.IsStack .Response.ClientAllocation.IsStack -}} |
| {{ "" }} No heap allocation necessary. |
| {{- else }} |
| {{- if not .Request.ClientAllocation.IsStack }} Request is heap-allocated. {{- end }} |
| {{- if not .Response.ClientAllocation.IsStack }} Response is heap-allocated. {{- end }} |
| {{- end }} |
| {{- end }} |
| |
| {{- define "ProtocolDeclaration" }} |
| {{- $protocol := . }} |
| {{ "" }} |
| {{- range .Methods }} |
| {{ EnsureNamespace .Request.WireCodingTable }} |
| extern "C" const fidl_type_t {{ .Request.WireCodingTable.Name }}; |
| {{ EnsureNamespace .Response.WireCodingTable }} |
| extern "C" const fidl_type_t {{ .Response.WireCodingTable.Name }}; |
| {{- end }} |
| {{ "" }} |
| {{ EnsureNamespace . }} |
| |
| {{- .Docs }} |
| class {{ .Name }} final { |
| {{ .Name }}() = delete; |
| public: |
| {{- range .Methods }} |
| {{- .Docs }} |
| class {{ .Marker.Self }} final { |
| {{ .Marker.Self }}() = delete; |
| }; |
| {{- end }} |
| }; |
| |
| {{- template "ProtocolDetailsDeclaration" . }} |
| {{- template "ProtocolDispatcherDeclaration" . }} |
| |
| {{- range .Methods }} |
| {{- if .HasRequest }} |
| {{- template "MethodRequestDeclaration" . }} |
| {{- end }} |
| {{- if .HasResponse }} |
| {{- template "MethodResponseDeclaration" . }} |
| {{- end }} |
| {{- end }} |
| |
| {{- range .ClientMethods -}} |
| {{- template "MethodResultDeclaration" . }} |
| {{- template "MethodUnownedResultDeclaration" . }} |
| {{- end }} |
| |
| {{- EnsureNamespace "::" }} |
| |
| // Methods to make a sync FIDL call directly on an unowned channel or a |
| // const reference to a |fidl::ClientEnd<{{ .WireType }}>|, |
| // avoiding setting up a client. |
| template<> |
| class {{ .WireCaller }} final { |
| public: |
| explicit {{ .WireCaller.Self }}(::fidl::UnownedClientEnd<{{ . }}> client_end) : |
| client_end_(client_end) {} |
| {{ "" }} |
| {{- /* Client-calling functions do not apply to events. */}} |
| {{- range .ClientMethods -}} |
| {{- .Docs }} |
| //{{ template "ClientAllocationComment" . }} |
| static {{ .WireResult }} {{ .Name }}( |
| ::fidl::UnownedClientEnd<{{ .Protocol }}> _client_end |
| {{- .RequestArgs | CalleeCommaParams }}) { |
| return {{ .WireResult }}(_client_end |
| {{- .RequestArgs | ForwardCommaParams -}} |
| ); |
| } |
| |
| {{- .Docs }} |
| //{{ template "ClientAllocationComment" . }} |
| {{ .WireResult }} {{ .Name }}({{- .RequestArgs | CalleeParams }}) && { |
| return {{ .WireResult }}(client_end_ |
| {{- .RequestArgs | ForwardCommaParams -}} |
| ); |
| } |
| {{ "" }} |
| {{- if or .RequestArgs .ResponseArgs }} |
| {{- .Docs }} |
| // Caller provides the backing storage for FIDL message via request and response buffers. |
| static {{ .WireUnownedResult }} {{ .Name }}({{ template "StaticCallSyncRequestCallerAllocateMethodArguments" . }}) { |
| return {{ .WireUnownedResult }}(_client_end |
| {{- if .RequestArgs -}} |
| , _request_buffer.data, _request_buffer.capacity |
| {{- end -}} |
| {{- .RequestArgs | ForwardCommaParams -}} |
| {{- if .HasResponse -}} |
| , _response_buffer.data, _response_buffer.capacity |
| {{- end -}}); |
| } |
| |
| {{- .Docs }} |
| // Caller provides the backing storage for FIDL message via request and response buffers. |
| {{ .WireUnownedResult }} {{ .Name }}({{ template "SyncRequestCallerAllocateMethodArguments" . }}) && { |
| return {{ .WireUnownedResult }}(client_end_ |
| {{- if .RequestArgs -}} |
| , _request_buffer.data, _request_buffer.capacity |
| {{- end -}} |
| {{- .RequestArgs | ForwardCommaParams -}} |
| {{- if .HasResponse -}} |
| , _response_buffer.data, _response_buffer.capacity |
| {{- end -}}); |
| } |
| |
| {{- end }} |
| {{ "" }} |
| {{- end }} |
| private: |
| ::fidl::UnownedClientEnd<{{ . }}> client_end_; |
| }; |
| |
| {{- template "ProtocolEventHandlerDeclaration" . }} |
| |
| template<> |
| class {{ .WireSyncClient }} final { |
| public: |
| WireSyncClient() = default; |
| |
| explicit WireSyncClient(::fidl::ClientEnd<{{ . }}> client_end) |
| : client_end_(std::move(client_end)) {} |
| |
| ~WireSyncClient() = default; |
| WireSyncClient(WireSyncClient&&) = default; |
| WireSyncClient& operator=(WireSyncClient&&) = default; |
| |
| const ::fidl::ClientEnd<{{ . }}>& client_end() const { return client_end_; } |
| ::fidl::ClientEnd<{{ . }}>& client_end() { return client_end_; } |
| |
| const ::zx::channel& channel() const { return client_end_.channel(); } |
| ::zx::channel* mutable_channel() { return &client_end_.channel(); } |
| {{ "" }} |
| {{- /* Client-calling functions do not apply to events. */}} |
| {{- range .ClientMethods -}} |
| {{- .Docs }} |
| //{{ template "ClientAllocationComment" . }} |
| {{ .WireResult }} {{ .Name }}({{ .RequestArgs | CalleeParams }}) { |
| return {{ .WireResult }}(this->client_end() |
| {{- .RequestArgs | ForwardCommaParams -}}); |
| } |
| {{ "" }} |
| {{- if or .RequestArgs .ResponseArgs }} |
| {{- .Docs }} |
| // Caller provides the backing storage for FIDL message via request and response buffers. |
| {{ .WireUnownedResult }} {{ .Name }}({{ template "SyncRequestCallerAllocateMethodArguments" . }}) { |
| return {{ .WireUnownedResult }}(this->client_end() |
| {{- if .RequestArgs -}} |
| , _request_buffer.data, _request_buffer.capacity |
| {{- end -}} |
| {{- .RequestArgs | ForwardCommaParams -}} |
| {{- if .HasResponse -}} |
| , _response_buffer.data, _response_buffer.capacity |
| {{- end -}}); |
| } |
| {{- end }} |
| {{ "" }} |
| {{- end }} |
| {{- if .Events }} |
| // Handle all possible events defined in this protocol. |
| // Blocks to consume exactly one message from the channel, then call the corresponding virtual |
| // method defined in |SyncEventHandler|. The return status of the handler function is folded with |
| // any transport-level errors and returned. |
| ::fidl::Result HandleOneEvent({{ .WireSyncEventHandler }}& event_handler) { |
| return event_handler.HandleOneEvent(client_end_); |
| } |
| {{- end }} |
| private: |
| ::fidl::ClientEnd<{{ . }}> client_end_; |
| }; |
| |
| |
| {{- template "ProtocolInterfaceDeclaration" . }} |
| {{- end }} |
| |
| {{- define "ProtocolTraits" -}} |
| {{ $protocol := . -}} |
| {{ range .Methods -}} |
| {{ $method := . -}} |
| {{- if .HasRequest }} |
| |
| template <> |
| struct IsFidlType<{{ .WireRequest }}> : public std::true_type {}; |
| template <> |
| struct IsFidlMessage<{{ .WireRequest }}> : public std::true_type {}; |
| static_assert(sizeof({{ .WireRequest }}) |
| == {{ .WireRequest }}::PrimarySize); |
| {{- range $index, $param := .RequestArgs }} |
| static_assert(offsetof({{ $method.WireRequest }}, {{ $param.Name }}) == {{ $param.Offset }}); |
| {{- end }} |
| {{- end }} |
| {{- if .HasResponse }} |
| |
| template <> |
| struct IsFidlType<{{ .WireResponse }}> : public std::true_type {}; |
| template <> |
| struct IsFidlMessage<{{ .WireResponse }}> : public std::true_type {}; |
| static_assert(sizeof({{ .WireResponse }}) |
| == {{ .WireResponse }}::PrimarySize); |
| {{- range $index, $param := .ResponseArgs }} |
| static_assert(offsetof({{ $method.WireResponse }}, {{ $param.Name }}) == {{ $param.Offset }}); |
| {{- end }} |
| {{- end }} |
| {{- end }} |
| {{- end }} |
| |
| {{- define "ProtocolDefinition" }} |
| {{ $protocol := . -}} |
| |
| {{- range .Methods }} |
| {{ EnsureNamespace .OrdinalName }} |
| [[maybe_unused]] |
| constexpr uint64_t {{ .OrdinalName.Name }} = {{ .Ordinal }}lu; |
| {{ EnsureNamespace .Request.WireCodingTable }} |
| extern "C" const fidl_type_t {{ .Request.WireCodingTable.Name }}; |
| {{ EnsureNamespace .Response.WireCodingTable }} |
| extern "C" const fidl_type_t {{ .Response.WireCodingTable.Name }}; |
| {{- end }} |
| |
| {{- /* Client-calling functions do not apply to events. */}} |
| {{- range .ClientMethods -}} |
| {{ "" }} |
| {{- template "MethodResultDefinition" . }} |
| {{- if or .RequestArgs .ResponseArgs }} |
| {{ "" }} |
| {{- template "MethodUnownedResultDefinition" . }} |
| {{- end }} |
| {{ "" }} |
| {{- end }} |
| |
| {{- range .ClientMethods }} |
| {{ "" }} |
| {{- template "ClientSyncRequestManagedMethodDefinition" . }} |
| {{- if or .RequestArgs .ResponseArgs }} |
| {{ "" }} |
| {{- template "ClientSyncRequestCallerAllocateMethodDefinition" . }} |
| {{- end }} |
| {{- if .HasResponse }} |
| {{ "" }} |
| {{- template "MethodResponseContextDefinition" . }} |
| {{- template "ClientAsyncRequestManagedMethodDefinition" . }} |
| {{- end }} |
| {{- end }} |
| {{ template "ClientDispatchDefinition" . }} |
| {{ "" }} |
| |
| {{- if .Events }} |
| {{- template "EventHandlerHandleOneEventMethodDefinition" . }} |
| {{- end }} |
| |
| {{- /* Server implementation */}} |
| {{ template "ProtocolDispatcherDefinition" . }} |
| |
| {{- if .Methods }} |
| {{ "" }} |
| {{- range .TwoWayMethods -}} |
| {{ "" }} |
| {{- template "ReplyManagedMethodDefinition" . }} |
| {{- if .Result }} |
| {{- template "ReplyManagedResultSuccessMethodDefinition" . }} |
| {{- template "ReplyManagedResultErrorMethodDefinition" . }} |
| {{- end }} |
| {{- if .ResponseArgs }} |
| {{ "" }} |
| {{- template "ReplyCallerAllocateMethodDefinition" . }} |
| {{- if .Result }} |
| {{- template "ReplyCallerAllocateResultSuccessMethodDefinition" . }} |
| {{- end }} |
| {{- end }} |
| {{ "" }} |
| {{- end }} |
| {{ "" }} |
| |
| {{- range .Methods }} |
| |
| {{- if .HasRequest }}{{ template "MethodRequestDefinition" . }}{{ end }} |
| {{ "" }} |
| |
| {{- if .HasResponse }}{{ template "MethodResponseDefinition" . }}{{ end }} |
| {{ "" }} |
| |
| {{- end }} |
| {{- end }} |
| |
| {{- end }} |
| ` |