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