@@ -1712,7 +1712,7 @@ where
17121712 pub ( crate ) fn record_type_parameters ( & self , record_name : & str ) -> Vec < TypeParameterUsage > {
17131713 let mut parameters = IndexMap :: < String , TypeParameterUsage > :: new ( ) ;
17141714 let mut visiting = std:: collections:: BTreeSet :: new ( ) ;
1715- self . collect_record_type_parameters ( record_name, & mut visiting, & mut parameters) ;
1715+ self . collect_record_type_parameters ( record_name, & mut visiting, & mut parameters, & |_| None ) ;
17161716 parameters. into_values ( ) . collect ( )
17171717 }
17181718
@@ -1721,14 +1721,16 @@ where
17211721 pub ( crate ) fn variant_type_parameters ( & self , variant_name : & str ) -> Vec < TypeParameterUsage > {
17221722 let mut parameters = IndexMap :: < String , TypeParameterUsage > :: new ( ) ;
17231723 let mut visiting = std:: collections:: BTreeSet :: new ( ) ;
1724- self . collect_variant_type_parameters ( variant_name, & mut visiting, & mut parameters) ;
1724+ self . collect_variant_type_parameters ( variant_name, & mut visiting, & mut parameters, & |_| {
1725+ None
1726+ } ) ;
17251727 parameters. into_values ( ) . collect ( )
17261728 }
17271729
17281730 pub ( crate ) fn type_parameters ( & self , value : & TypeSpec < F > ) -> Vec < TypeParameterUsage > {
17291731 let mut parameters = IndexMap :: < String , TypeParameterUsage > :: new ( ) ;
17301732 let mut visiting = std:: collections:: BTreeSet :: new ( ) ;
1731- self . collect_type_parameters ( value, & mut visiting, & mut parameters) ;
1733+ self . collect_type_parameters ( value, & mut visiting, & mut parameters, & |_| None ) ;
17321734 parameters. into_values ( ) . collect ( )
17331735 }
17341736
@@ -1737,6 +1739,7 @@ where
17371739 record_name : & str ,
17381740 visiting : & mut std:: collections:: BTreeSet < String > ,
17391741 parameters : & mut IndexMap < String , TypeParameterUsage > ,
1742+ proto_record : & dyn Fn ( & F :: Proto ) -> Option < String > ,
17401743 ) {
17411744 if !visiting. insert ( record_name. to_string ( ) ) {
17421745 return ;
@@ -1751,7 +1754,7 @@ where
17511754 {
17521755 continue ;
17531756 }
1754- self . collect_type_parameters ( & field. field_type , visiting, parameters) ;
1757+ self . collect_type_parameters ( & field. field_type , visiting, parameters, proto_record ) ;
17551758 }
17561759 }
17571760 visiting. remove ( record_name) ;
@@ -1762,14 +1765,15 @@ where
17621765 variant_name : & str ,
17631766 visiting : & mut std:: collections:: BTreeSet < String > ,
17641767 parameters : & mut IndexMap < String , TypeParameterUsage > ,
1768+ proto_record : & dyn Fn ( & F :: Proto ) -> Option < String > ,
17651769 ) {
17661770 if !visiting. insert ( variant_name. to_string ( ) ) {
17671771 return ;
17681772 }
17691773 if let Some ( variant) = self . variant ( variant_name) {
17701774 for case in & variant. cases {
17711775 if let Some ( payload) = & case. payload {
1772- self . collect_type_parameters ( payload, visiting, parameters) ;
1776+ self . collect_type_parameters ( payload, visiting, parameters, proto_record ) ;
17731777 }
17741778 }
17751779 }
@@ -1781,6 +1785,7 @@ where
17811785 value : & TypeSpec < F > ,
17821786 visiting : & mut std:: collections:: BTreeSet < String > ,
17831787 parameters : & mut IndexMap < String , TypeParameterUsage > ,
1788+ proto_record : & dyn Fn ( & F :: Proto ) -> Option < String > ,
17841789 ) {
17851790 match value {
17861791 TypeSpec :: TypeParameter ( parameter) => {
@@ -1794,33 +1799,49 @@ where
17941799 }
17951800 }
17961801 TypeSpec :: Option ( inner) | TypeSpec :: List ( inner) => {
1797- self . collect_type_parameters ( inner, visiting, parameters)
1802+ self . collect_type_parameters ( inner, visiting, parameters, proto_record )
17981803 }
17991804 TypeSpec :: Tuple ( items) => {
18001805 for item in items {
1801- self . collect_type_parameters ( item, visiting, parameters) ;
1806+ self . collect_type_parameters ( item, visiting, parameters, proto_record ) ;
18021807 }
18031808 }
18041809 TypeSpec :: Map ( key, value) => {
1805- self . collect_type_parameters ( key, visiting, parameters) ;
1806- self . collect_type_parameters ( value, visiting, parameters) ;
1810+ self . collect_type_parameters ( key, visiting, parameters, proto_record ) ;
1811+ self . collect_type_parameters ( value, visiting, parameters, proto_record ) ;
18071812 }
18081813 TypeSpec :: Result { ok, err } => {
18091814 if let Some ( ok) = ok {
1810- self . collect_type_parameters ( ok, visiting, parameters) ;
1815+ self . collect_type_parameters ( ok, visiting, parameters, proto_record ) ;
18111816 }
18121817 if let Some ( err) = err {
1813- self . collect_type_parameters ( err, visiting, parameters) ;
1818+ self . collect_type_parameters ( err, visiting, parameters, proto_record ) ;
18141819 }
18151820 }
1816- TypeSpec :: Record ( record) => {
1817- self . collect_record_type_parameters ( record. as_ref ( ) , visiting, parameters)
1818- }
1819- TypeSpec :: Variant ( variant) => {
1820- self . collect_variant_type_parameters ( variant. as_ref ( ) , visiting, parameters)
1821- }
1821+ TypeSpec :: Record ( record) => self . collect_record_type_parameters (
1822+ record. as_ref ( ) ,
1823+ visiting,
1824+ parameters,
1825+ proto_record,
1826+ ) ,
1827+ TypeSpec :: Variant ( variant) => self . collect_variant_type_parameters (
1828+ variant. as_ref ( ) ,
1829+ visiting,
1830+ parameters,
1831+ proto_record,
1832+ ) ,
18221833 TypeSpec :: External ( ExternalTypeSpec :: Alias ( alias) ) => {
1823- self . collect_type_parameters ( & alias. target , visiting, parameters)
1834+ self . collect_type_parameters ( & alias. target , visiting, parameters, proto_record)
1835+ }
1836+ TypeSpec :: External ( ExternalTypeSpec :: Proto ( proto) ) => {
1837+ if let Some ( record_name) = proto_record ( proto) {
1838+ self . collect_record_type_parameters (
1839+ & record_name,
1840+ visiting,
1841+ parameters,
1842+ proto_record,
1843+ ) ;
1844+ }
18241845 }
18251846 TypeSpec :: Bool
18261847 | TypeSpec :: Int ( _)
@@ -1830,12 +1851,35 @@ where
18301851 | TypeSpec :: Enum ( _)
18311852 | TypeSpec :: Flags ( _)
18321853 | TypeSpec :: Resource ( _)
1833- | TypeSpec :: External ( ExternalTypeSpec :: Proto ( _) )
18341854 | TypeSpec :: External ( ExternalTypeSpec :: Json ( _) ) => { }
18351855 }
18361856 }
18371857}
18381858
1859+ impl < F > ApiSpec < F >
1860+ where
1861+ F : TypeFamily ,
1862+ F :: Proto : AsRef < str > ,
1863+ F :: Record : AsRef < str > ,
1864+ F :: Variant : AsRef < str > ,
1865+ {
1866+ /// Like `type_parameters`, but also walks the record behind each proto type. Before planning, a
1867+ /// proto-backed record is named by its proto type, so the plain walk stops there.
1868+ pub ( crate ) fn type_parameters_through_protos (
1869+ & self ,
1870+ value : & TypeSpec < F > ,
1871+ ) -> Vec < TypeParameterUsage > {
1872+ let mut parameters = IndexMap :: < String , TypeParameterUsage > :: new ( ) ;
1873+ let mut visiting = std:: collections:: BTreeSet :: new ( ) ;
1874+ let proto_record = |proto : & F :: Proto | {
1875+ self . record_for_proto ( proto. as_ref ( ) )
1876+ . map ( |record| record. full_name . clone ( ) )
1877+ } ;
1878+ self . collect_type_parameters ( value, & mut visiting, & mut parameters, & proto_record) ;
1879+ parameters. into_values ( ) . collect ( )
1880+ }
1881+ }
1882+
18391883#[ derive( Debug , Clone , PartialEq ) ]
18401884pub struct FunctionFieldSpec < F : TypeFamily = AuthoredFamily > {
18411885 pub primary : bool ,
0 commit comments