1use crate::bedrock::sandbox_construction::ComponentSandbox;
6use crate::capability_source::{BuiltinCapabilities, NamespaceCapabilities};
7use crate::error::ComponentInstanceError;
8use crate::policy::GlobalPolicyChecker;
9use crate::resolving::{ComponentAddress, ComponentResolutionContext, ResolverError};
10use async_trait::async_trait;
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 sandbox::{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 uses(&self) -> Box<[UseDecl]>;
145
146 fn exposes(&self) -> Box<[ExposeDecl]>;
148
149 fn offers(&self) -> Box<[OfferDecl]>;
152
153 fn capabilities(&self) -> Box<[CapabilityDecl]>;
155
156 fn collections(&self) -> Box<[CollectionDecl]>;
158
159 fn get_child(&self, moniker: &BorrowedChildName) -> Option<Arc<Self::Component>>;
161
162 fn children_in_collection(&self, collection: &Name) -> Vec<(ChildName, Arc<Self::Component>)>;
164
165 async fn address(&self) -> Result<ComponentAddress, ResolverError>;
168
169 fn context_to_resolve_children(&self) -> Option<ComponentResolutionContext>;
173}
174
175pub trait ResolvedInstanceInterfaceExt: ResolvedInstanceInterface {
178 fn offer_source_exists(&self, source: &OfferSource) -> bool {
181 match source {
182 OfferSource::Framework
183 | OfferSource::Self_
184 | OfferSource::Parent
185 | OfferSource::Void => true,
186 OfferSource::Child(cm_rust::ChildRef { name, collection }) => {
187 let child_moniker = match ChildName::try_new(
188 name.as_str(),
189 collection.as_ref().map(|c| c.as_str()),
190 ) {
191 Ok(m) => m,
192 Err(_) => return false,
193 };
194 self.get_child(&child_moniker).is_some()
195 }
196 OfferSource::Collection(collection_name) => IntoIterator::into_iter(self.collections())
197 .any(|collection| collection.name == *collection_name),
198 OfferSource::Capability(capability_name) => {
199 IntoIterator::into_iter(self.capabilities())
200 .any(|capability| capability.name() == capability_name)
201 }
202 }
203 }
204}
205
206impl<T: ResolvedInstanceInterface> ResolvedInstanceInterfaceExt for T {}
207
208#[async_trait]
213impl<T> ResolvedInstanceInterface for T
214where
215 T: std::ops::Deref + Send + Sync,
216 T::Target: ResolvedInstanceInterface,
217{
218 type Component = <T::Target as ResolvedInstanceInterface>::Component;
219
220 fn uses(&self) -> Box<[UseDecl]> {
221 T::Target::uses(&*self)
222 }
223
224 fn exposes(&self) -> Box<[ExposeDecl]> {
225 T::Target::exposes(&*self)
226 }
227
228 fn offers(&self) -> Box<[cm_rust::offer::OfferDecl]> {
229 T::Target::offers(&*self)
230 }
231
232 fn capabilities(&self) -> Box<[cm_rust::CapabilityDecl]> {
233 T::Target::capabilities(&*self)
234 }
235
236 fn collections(&self) -> Box<[cm_rust::CollectionDecl]> {
237 T::Target::collections(&*self)
238 }
239
240 fn get_child(&self, moniker: &BorrowedChildName) -> Option<Arc<Self::Component>> {
241 T::Target::get_child(&*self, moniker)
242 }
243
244 fn children_in_collection(&self, collection: &Name) -> Vec<(ChildName, Arc<Self::Component>)> {
245 T::Target::children_in_collection(&*self, collection)
246 }
247
248 async fn address(&self) -> Result<ComponentAddress, ResolverError> {
249 T::Target::address(&*self).await
250 }
251
252 fn context_to_resolve_children(&self) -> Option<ComponentResolutionContext> {
253 T::Target::context_to_resolve_children(&*self)
254 }
255}
256
257#[derive(Derivative)]
261#[derivative(Clone(bound = ""), Default(bound = ""), Debug)]
262pub struct WeakComponentInstanceInterface<C: ComponentInstanceInterface> {
263 #[derivative(Debug = "ignore")]
264 inner: Weak<C>,
265 pub moniker: Moniker,
266}
267
268impl<C: ComponentInstanceInterface> WeakComponentInstanceInterface<C> {
269 pub fn new(component: &Arc<C>) -> Self {
270 Self { inner: Arc::downgrade(component), moniker: component.moniker().clone() }
271 }
272
273 pub fn invalid() -> Self {
275 Self { inner: Weak::new(), moniker: Moniker::new(&[]) }
276 }
277
278 pub fn upgrade(&self) -> Result<Arc<C>, ComponentInstanceError> {
281 self.inner
282 .upgrade()
283 .ok_or_else(|| ComponentInstanceError::instance_not_found(self.moniker.clone()))
284 }
285}
286
287impl<C: ComponentInstanceInterface> From<&Arc<C>> for WeakComponentInstanceInterface<C> {
288 fn from(component: &Arc<C>) -> Self {
289 Self { inner: Arc::downgrade(component), moniker: component.moniker().clone() }
290 }
291}
292
293impl<C: ComponentInstanceInterface + 'static> TryFrom<WeakInstanceToken>
294 for WeakComponentInstanceInterface<C>
295{
296 type Error = ();
297
298 fn try_from(
299 weak_component_token: WeakInstanceToken,
300 ) -> Result<WeakComponentInstanceInterface<C>, Self::Error> {
301 let weak_extended: WeakExtendedInstanceInterface<C> = weak_component_token.try_into()?;
302 match weak_extended {
303 WeakExtendedInstanceInterface::Component(weak_component) => Ok(weak_component),
304 WeakExtendedInstanceInterface::AboveRoot(_) => Err(()),
305 }
306 }
307}
308
309impl<C: ComponentInstanceInterface + 'static> PartialEq for WeakComponentInstanceInterface<C> {
310 fn eq(&self, other: &Self) -> bool {
311 self.inner.ptr_eq(&other.inner) && self.moniker == other.moniker
312 }
313}
314
315#[derive(Debug, Clone)]
317pub enum ExtendedInstanceInterface<C: ComponentInstanceInterface> {
318 Component(Arc<C>),
319 AboveRoot(Arc<C::TopInstance>),
320}
321
322#[derive(Derivative)]
324#[derivative(Clone(bound = ""), Debug(bound = ""))]
325pub enum WeakExtendedInstanceInterface<C: ComponentInstanceInterface> {
326 Component(WeakComponentInstanceInterface<C>),
327 AboveRoot(Weak<C::TopInstance>),
328}
329
330impl<C: ComponentInstanceInterface + 'static> WeakInstanceTokenAny
331 for WeakExtendedInstanceInterface<C>
332{
333 fn as_any(&self) -> &dyn std::any::Any {
334 self
335 }
336}
337
338impl<C: ComponentInstanceInterface> WeakExtendedInstanceInterface<C> {
339 pub fn upgrade(&self) -> Result<ExtendedInstanceInterface<C>, ComponentInstanceError> {
342 match self {
343 WeakExtendedInstanceInterface::Component(p) => {
344 Ok(ExtendedInstanceInterface::Component(p.upgrade()?))
345 }
346 WeakExtendedInstanceInterface::AboveRoot(p) => {
347 Ok(ExtendedInstanceInterface::AboveRoot(
348 p.upgrade().ok_or_else(ComponentInstanceError::cm_instance_unavailable)?,
349 ))
350 }
351 }
352 }
353
354 pub fn extended_moniker(&self) -> ExtendedMoniker {
355 match self {
356 Self::Component(p) => ExtendedMoniker::ComponentInstance(p.moniker.clone()),
357 Self::AboveRoot(_) => ExtendedMoniker::ComponentManager,
358 }
359 }
360}
361
362impl<C: ComponentInstanceInterface> From<&ExtendedInstanceInterface<C>>
363 for WeakExtendedInstanceInterface<C>
364{
365 fn from(extended: &ExtendedInstanceInterface<C>) -> Self {
366 match extended {
367 ExtendedInstanceInterface::Component(component) => {
368 WeakExtendedInstanceInterface::Component(WeakComponentInstanceInterface::new(
369 component,
370 ))
371 }
372 ExtendedInstanceInterface::AboveRoot(top_instance) => {
373 WeakExtendedInstanceInterface::AboveRoot(Arc::downgrade(top_instance))
374 }
375 }
376 }
377}
378
379impl<C: ComponentInstanceInterface + 'static> TryFrom<WeakInstanceToken>
380 for WeakExtendedInstanceInterface<C>
381{
382 type Error = ();
383
384 fn try_from(
385 weak_component_token: WeakInstanceToken,
386 ) -> Result<WeakExtendedInstanceInterface<C>, Self::Error> {
387 weak_component_token
388 .inner
389 .as_any()
390 .downcast_ref::<WeakExtendedInstanceInterface<C>>()
391 .cloned()
392 .ok_or(())
393 }
394}
395
396pub trait TopInstanceInterface: Sized + std::fmt::Debug {
398 fn namespace_capabilities(&self) -> &NamespaceCapabilities;
399
400 fn builtin_capabilities(&self) -> &BuiltinCapabilities;
401}
402
403#[cfg(test)]
404pub mod tests {
405 use super::*;
406 use crate::bedrock::sandbox_construction::ComponentSandbox;
407
408 #[derive(Debug)]
409 pub struct TestTopInstance {}
410
411 impl TopInstanceInterface for TestTopInstance {
412 fn namespace_capabilities(&self) -> &NamespaceCapabilities {
413 todo!()
414 }
415
416 fn builtin_capabilities(&self) -> &BuiltinCapabilities {
417 todo!()
418 }
419 }
420
421 pub struct TestComponent {}
422
423 #[async_trait]
424 impl ComponentInstanceInterface for TestComponent {
425 type TopInstance = TestTopInstance;
426
427 fn child_moniker(&self) -> Option<&BorrowedChildName> {
428 todo!()
429 }
430
431 fn moniker(&self) -> &Moniker {
432 todo!()
433 }
434
435 fn url(&self) -> &Url {
436 todo!()
437 }
438
439 fn config_parent_overrides(&self) -> Option<&[cm_rust::ConfigOverride]> {
440 todo!()
441 }
442
443 fn policy_checker(&self) -> &GlobalPolicyChecker {
444 todo!()
445 }
446
447 fn component_id_index(&self) -> &component_id_index::Index {
448 todo!()
449 }
450
451 fn try_get_parent(
452 &self,
453 ) -> Result<ExtendedInstanceInterface<Self>, ComponentInstanceError> {
454 todo!()
455 }
456
457 async fn lock_resolved_state<'a>(
458 self: &'a Arc<Self>,
459 ) -> Result<Box<dyn ResolvedInstanceInterface<Component = Self> + 'a>, ComponentInstanceError>
460 {
461 todo!()
462 }
463
464 async fn component_sandbox(
465 self: &Arc<Self>,
466 ) -> Result<ComponentSandbox, ComponentInstanceError> {
467 todo!()
468 }
469 }
470}