1use crate::bedrock::sandbox_construction::ComponentSandbox;
6use crate::error::ComponentInstanceError;
7use crate::policy::GlobalPolicyChecker;
8use crate::resolving::{ComponentAddress, ComponentResolutionContext, ResolverError};
9use async_trait::async_trait;
10use capability_source::{BuiltinCapabilities, NamespaceCapabilities};
11use cm_rust::offer::{OfferDecl, OfferSource};
12use cm_rust::{CapabilityDecl, CollectionDecl, ExposeDecl, UseDecl};
13use cm_types::{Name, Url};
14use derivative::Derivative;
15use moniker::{BorrowedChildName, ChildName, ExtendedMoniker, Moniker};
16use runtime_capabilities::{WeakInstanceToken, WeakInstanceTokenAny};
17use std::clone::Clone;
18use std::sync::{Arc, Weak};
19
20#[async_trait]
22pub trait ComponentInstanceInterface: Sized + Send + Sync {
23 type TopInstance: TopInstanceInterface + Send + Sync;
24
25 fn as_weak(self: &Arc<Self>) -> WeakComponentInstanceInterface<Self> {
27 WeakComponentInstanceInterface::new(self)
28 }
29
30 fn child_moniker(&self) -> Option<&BorrowedChildName> {
33 self.moniker().leaf()
34 }
35
36 fn moniker(&self) -> &Moniker;
38
39 fn url(&self) -> &Url;
41
42 fn config_parent_overrides(&self) -> Option<&[cm_rust::ConfigOverride]>;
44
45 fn policy_checker(&self) -> &GlobalPolicyChecker;
47
48 fn component_id_index(&self) -> &component_id_index::Index;
50
51 fn try_get_parent(&self) -> Result<ExtendedInstanceInterface<Self>, ComponentInstanceError>;
53
54 async fn lock_resolved_state<'a>(
64 self: &'a Arc<Self>,
65 ) -> Result<Box<dyn ResolvedInstanceInterface<Component = Self> + 'a>, ComponentInstanceError>;
66
67 async fn component_sandbox(
69 self: &Arc<Self>,
70 ) -> Result<ComponentSandbox, ComponentInstanceError>;
71
72 async fn find_extended_instance(
77 self: &Arc<Self>,
78 moniker: &ExtendedMoniker,
79 ) -> Result<ExtendedInstanceInterface<Self>, ComponentInstanceError> {
80 match moniker {
81 ExtendedMoniker::ComponentInstance(moniker) => {
82 Ok(ExtendedInstanceInterface::Component(self.find_absolute(moniker).await?))
83 }
84 ExtendedMoniker::ComponentManager => {
85 Ok(ExtendedInstanceInterface::AboveRoot(self.find_above_root()?))
86 }
87 }
88 }
89
90 async fn find_absolute(
94 self: &Arc<Self>,
95 target_moniker: &Moniker,
96 ) -> Result<Arc<Self>, ComponentInstanceError> {
97 let mut current = self.clone();
98 while !target_moniker.has_prefix(current.moniker()) {
99 match current.try_get_parent()? {
100 ExtendedInstanceInterface::AboveRoot(_) => panic!(
101 "the current component ({}) must be root, but it's not a prefix for {}",
102 current.moniker(),
103 target_moniker
104 ),
105 ExtendedInstanceInterface::Component(parent) => current = parent,
106 }
107 }
108 while current.moniker() != target_moniker {
109 let remaining_path = target_moniker.strip_prefix(current.moniker()).expect(
110 "previous loop will only exit when current.moniker() is a prefix of target_moniker",
111 );
112 for moniker_part in remaining_path.path() {
113 let child = current.lock_resolved_state().await?.get_child(moniker_part).ok_or(
114 ComponentInstanceError::InstanceNotFound {
115 moniker: current.moniker().child(moniker_part.into()),
116 },
117 )?;
118 current = child;
119 }
120 }
121 Ok(current)
122 }
123
124 fn find_above_root(self: &Arc<Self>) -> Result<Arc<Self::TopInstance>, ComponentInstanceError> {
127 let mut current = self.clone();
128 loop {
129 match current.try_get_parent()? {
130 ExtendedInstanceInterface::AboveRoot(top_instance) => return Ok(top_instance),
131 ExtendedInstanceInterface::Component(parent) => current = parent,
132 }
133 }
134 }
135}
136
137#[async_trait]
139pub trait ResolvedInstanceInterface: Send + Sync {
140 type Component;
142
143 fn try_uses(&self) -> Option<Box<[UseDecl]>>;
147
148 fn try_exposes(&self) -> Option<Box<[ExposeDecl]>>;
152
153 fn try_offers(&self) -> Option<Box<[OfferDecl]>>;
158
159 fn try_capabilities(&self) -> Option<Box<[CapabilityDecl]>>;
163
164 fn try_collections(&self) -> Option<Box<[CollectionDecl]>>;
168
169 fn get_child(&self, moniker: &BorrowedChildName) -> Option<Arc<Self::Component>>;
171
172 fn children_in_collection(&self, collection: &Name) -> Vec<(ChildName, Arc<Self::Component>)>;
174
175 async fn address(&self) -> Result<ComponentAddress, ResolverError>;
178
179 fn context_to_resolve_children(&self) -> Option<ComponentResolutionContext>;
183}
184
185pub trait ResolvedInstanceInterfaceExt: ResolvedInstanceInterface {
188 fn try_offer_source_exists(&self, source: &OfferSource) -> Option<bool> {
194 match source {
195 OfferSource::Framework
196 | OfferSource::Self_
197 | OfferSource::Parent
198 | OfferSource::Void => Some(true),
199 OfferSource::Child(cm_rust::ChildRef { name, collection }) => {
200 let child_moniker = match ChildName::try_new(
201 name.as_str(),
202 collection.as_ref().map(|c| c.as_str()),
203 ) {
204 Ok(m) => m,
205 Err(_) => return Some(false),
206 };
207 Some(self.get_child(&child_moniker).is_some())
208 }
209 OfferSource::Collection(collection_name) => self
210 .try_collections()
211 .map(|c| c.iter().any(|collection| collection.name == *collection_name)),
212 OfferSource::Capability(capability_name) => self
213 .try_capabilities()
214 .map(|c| c.iter().any(|capability| capability.name() == capability_name)),
215 }
216 }
217}
218
219impl<T: ResolvedInstanceInterface> ResolvedInstanceInterfaceExt for T {}
220
221#[async_trait]
226impl<T> ResolvedInstanceInterface for T
227where
228 T: std::ops::Deref + Send + Sync,
229 T::Target: ResolvedInstanceInterface,
230{
231 type Component = <T::Target as ResolvedInstanceInterface>::Component;
232
233 fn try_uses(&self) -> Option<Box<[UseDecl]>> {
234 T::Target::try_uses(&*self)
235 }
236
237 fn try_exposes(&self) -> Option<Box<[ExposeDecl]>> {
238 T::Target::try_exposes(&*self)
239 }
240
241 fn try_offers(&self) -> Option<Box<[cm_rust::offer::OfferDecl]>> {
242 T::Target::try_offers(&*self)
243 }
244
245 fn try_capabilities(&self) -> Option<Box<[cm_rust::CapabilityDecl]>> {
246 T::Target::try_capabilities(&*self)
247 }
248
249 fn try_collections(&self) -> Option<Box<[cm_rust::CollectionDecl]>> {
250 T::Target::try_collections(&*self)
251 }
252
253 fn get_child(&self, moniker: &BorrowedChildName) -> Option<Arc<Self::Component>> {
254 T::Target::get_child(&*self, moniker)
255 }
256
257 fn children_in_collection(&self, collection: &Name) -> Vec<(ChildName, Arc<Self::Component>)> {
258 T::Target::children_in_collection(&*self, collection)
259 }
260
261 async fn address(&self) -> Result<ComponentAddress, ResolverError> {
262 T::Target::address(&*self).await
263 }
264
265 fn context_to_resolve_children(&self) -> Option<ComponentResolutionContext> {
266 T::Target::context_to_resolve_children(&*self)
267 }
268}
269
270#[derive(Derivative)]
274#[derivative(Clone(bound = ""), Default(bound = ""), Debug)]
275pub struct WeakComponentInstanceInterface<C: ComponentInstanceInterface> {
276 #[derivative(Debug = "ignore")]
277 inner: Weak<C>,
278 pub moniker: Moniker,
279}
280
281impl<C: ComponentInstanceInterface> WeakComponentInstanceInterface<C> {
282 pub fn new(component: &Arc<C>) -> Self {
283 Self { inner: Arc::downgrade(component), moniker: component.moniker().clone() }
284 }
285
286 pub fn invalid() -> Self {
288 Self { inner: Weak::new(), moniker: Moniker::new(&[]) }
289 }
290
291 pub fn upgrade(&self) -> Result<Arc<C>, ComponentInstanceError> {
294 self.inner
295 .upgrade()
296 .ok_or_else(|| ComponentInstanceError::instance_not_found(self.moniker.clone()))
297 }
298}
299
300impl<C: ComponentInstanceInterface> From<&Arc<C>> for WeakComponentInstanceInterface<C> {
301 fn from(component: &Arc<C>) -> Self {
302 Self { inner: Arc::downgrade(component), moniker: component.moniker().clone() }
303 }
304}
305
306impl<C: ComponentInstanceInterface + 'static> TryFrom<Arc<WeakInstanceToken>>
307 for WeakComponentInstanceInterface<C>
308{
309 type Error = ();
310
311 fn try_from(
312 weak_component_token: Arc<WeakInstanceToken>,
313 ) -> Result<WeakComponentInstanceInterface<C>, Self::Error> {
314 let weak_extended: WeakExtendedInstanceInterface<C> = weak_component_token.try_into()?;
315 match weak_extended {
316 WeakExtendedInstanceInterface::Component(weak_component) => Ok(weak_component),
317 WeakExtendedInstanceInterface::AboveRoot(_) => Err(()),
318 }
319 }
320}
321
322impl<C: ComponentInstanceInterface + 'static> PartialEq for WeakComponentInstanceInterface<C> {
323 fn eq(&self, other: &Self) -> bool {
324 self.inner.ptr_eq(&other.inner) && self.moniker == other.moniker
325 }
326}
327
328#[derive(Debug, Clone)]
330pub enum ExtendedInstanceInterface<C: ComponentInstanceInterface> {
331 Component(Arc<C>),
332 AboveRoot(Arc<C::TopInstance>),
333}
334
335#[derive(Derivative)]
337#[derivative(Clone(bound = ""), Debug(bound = ""))]
338pub enum WeakExtendedInstanceInterface<C: ComponentInstanceInterface> {
339 Component(WeakComponentInstanceInterface<C>),
340 AboveRoot(Weak<C::TopInstance>),
341}
342
343impl<C: ComponentInstanceInterface + 'static> WeakInstanceTokenAny
344 for WeakExtendedInstanceInterface<C>
345{
346 fn as_any(&self) -> &dyn std::any::Any {
347 self
348 }
349}
350
351impl<C: ComponentInstanceInterface> WeakExtendedInstanceInterface<C> {
352 pub fn upgrade(&self) -> Result<ExtendedInstanceInterface<C>, ComponentInstanceError> {
355 match self {
356 WeakExtendedInstanceInterface::Component(p) => {
357 Ok(ExtendedInstanceInterface::Component(p.upgrade()?))
358 }
359 WeakExtendedInstanceInterface::AboveRoot(p) => {
360 Ok(ExtendedInstanceInterface::AboveRoot(
361 p.upgrade().ok_or_else(ComponentInstanceError::cm_instance_unavailable)?,
362 ))
363 }
364 }
365 }
366
367 pub fn extended_moniker(&self) -> ExtendedMoniker {
368 match self {
369 Self::Component(p) => ExtendedMoniker::ComponentInstance(p.moniker.clone()),
370 Self::AboveRoot(_) => ExtendedMoniker::ComponentManager,
371 }
372 }
373}
374
375impl<C: ComponentInstanceInterface> From<&ExtendedInstanceInterface<C>>
376 for WeakExtendedInstanceInterface<C>
377{
378 fn from(extended: &ExtendedInstanceInterface<C>) -> Self {
379 match extended {
380 ExtendedInstanceInterface::Component(component) => {
381 WeakExtendedInstanceInterface::Component(WeakComponentInstanceInterface::new(
382 component,
383 ))
384 }
385 ExtendedInstanceInterface::AboveRoot(top_instance) => {
386 WeakExtendedInstanceInterface::AboveRoot(Arc::downgrade(top_instance))
387 }
388 }
389 }
390}
391
392impl<C: ComponentInstanceInterface + 'static> TryFrom<Arc<WeakInstanceToken>>
393 for WeakExtendedInstanceInterface<C>
394{
395 type Error = ();
396
397 fn try_from(
398 weak_component_token: Arc<WeakInstanceToken>,
399 ) -> Result<WeakExtendedInstanceInterface<C>, Self::Error> {
400 weak_component_token
401 .inner
402 .as_any()
403 .downcast_ref::<WeakExtendedInstanceInterface<C>>()
404 .cloned()
405 .ok_or(())
406 }
407}
408
409pub trait TopInstanceInterface: Sized + std::fmt::Debug {
411 fn namespace_capabilities(&self) -> &NamespaceCapabilities;
412
413 fn builtin_capabilities(&self) -> &BuiltinCapabilities;
414}
415
416#[cfg(test)]
417pub mod tests {
418 use super::*;
419 use crate::bedrock::sandbox_construction::ComponentSandbox;
420
421 #[derive(Debug)]
422 pub struct TestTopInstance {}
423
424 impl TopInstanceInterface for TestTopInstance {
425 fn namespace_capabilities(&self) -> &NamespaceCapabilities {
426 todo!()
427 }
428
429 fn builtin_capabilities(&self) -> &BuiltinCapabilities {
430 todo!()
431 }
432 }
433
434 pub struct TestComponent {}
435
436 #[async_trait]
437 impl ComponentInstanceInterface for TestComponent {
438 type TopInstance = TestTopInstance;
439
440 fn child_moniker(&self) -> Option<&BorrowedChildName> {
441 todo!()
442 }
443
444 fn moniker(&self) -> &Moniker {
445 todo!()
446 }
447
448 fn url(&self) -> &Url {
449 todo!()
450 }
451
452 fn config_parent_overrides(&self) -> Option<&[cm_rust::ConfigOverride]> {
453 todo!()
454 }
455
456 fn policy_checker(&self) -> &GlobalPolicyChecker {
457 todo!()
458 }
459
460 fn component_id_index(&self) -> &component_id_index::Index {
461 todo!()
462 }
463
464 fn try_get_parent(
465 &self,
466 ) -> Result<ExtendedInstanceInterface<Self>, ComponentInstanceError> {
467 todo!()
468 }
469
470 async fn lock_resolved_state<'a>(
471 self: &'a Arc<Self>,
472 ) -> Result<Box<dyn ResolvedInstanceInterface<Component = Self> + 'a>, ComponentInstanceError>
473 {
474 todo!()
475 }
476
477 async fn component_sandbox(
478 self: &Arc<Self>,
479 ) -> Result<ComponentSandbox, ComponentInstanceError> {
480 todo!()
481 }
482 }
483}