// Copyright 2021 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.
use { protocols::FidlProtocol, fidl::endpoints::DiscoverableProtocolMarker, proc_macro::TokenStream, quote::quote, std::collections::hash_map::Entry, protocols_dependencies::{DependencyGraph, Node, VerifyError}, };
#[proc_macro] pub fn generate_protocol_map(_item: TokenStream) -> TokenStream { let mut graph = DependencyGraph::default(); {% for dep in deps %} let {{ dep.lib }}_node = Node::new( // Protocol name. <<{{ dep.lib }}::ProtocolType as FidlProtocol>::Protocol as DiscoverableProtocolMarker>::PROTOCOL_NAME, // Build target. “{{ dep.target }}”.to_owned(),
// Deps. {{ dep.lib }}::PROTOCOL_DEPS, ); match graph.nodes.entry({{ dep.lib }}_node.protocol) { Entry::Occupied(e) => { panic!("Protocol endpoint for {} already registered with library at {}", {{ dep.lib }}_node.protocol, e.get().build_target); } Entry::Vacant(i) => { i.insert({{ dep.lib }}_node) } }; {% endfor %} if let Err(e) = graph.verify() { match e { VerifyError::CycleFound(path) => { let errors_string = path .into_iter() .map(|n| format!("\n\t{}, implemented in {}", n.protocol, n.build_target)) .collect::<Vec<_>>() .join(""); panic!("Dependency cycle detected between the following protocols: {}", errors_string); } VerifyError::InvalidDependencyError(m) => panic!("{}", m), } } let res = quote! { { use fidl::endpoints::DiscoverableProtocolMarker; use protocols::{FidlStreamHandler, FidlProtocol}; use protocols::NameToStreamHandlerMap; let mut map = NameToStreamHandlerMap::new(); {% for dep in deps %} map.insert( <<{{ dep.lib }}::ProtocolType as FidlProtocol>::Protocol as DiscoverableProtocolMarker>::PROTOCOL_NAME.to_owned(), Box::new(<{{dep.lib }}::ProtocolType as FidlProtocol>::StreamHandler::default()), ); {% endfor %} map } }; TokenStream::from(res)
}