13. 再現性さいげんせい・schema識別しきべつ・契約けいやくの判定はんてい
方針ほうしん
共有きょうゆうする意味いみと実装固有じっそうこゆうのアルゴリズムを分わける。digestの自己参照じこさんしょう、言語同士げんごどうしの相互埋そうごうめ込こみによるhash循環じゅんかん、source順じゅんと識別子順しきべつしじゅんの混同こんどうを避さける。
1. digest
Bytes32のdigest関数かんすうはSHA-256に固定こていする。sourceとresourceのcontent digestは元もとのbyte列れつにそのまま適用てきようする。BOM、改行かいぎょう、空白くうはくも内容ないようの一部いちぶであり、Unicode正規化せいきかを行おこなわない。SourceContentのURIはhostが付つける論理的ろんりてきな絶対ぜったいlocatorであり、SourceRefの同一性どういつせいとは別べつに保持ほじする。coreはOS path canonicalizationをしない。
このlocatorの字句じくprofileはASCIIのscheme [A-Za-z][A-Za-z0-9+.-]*: と空からでない後続文字列こうぞくもじれつである。control・未みescapeの空白くうはくを拒否きょひし、% は2桁けたのASCII hexが続つづく場合ばあいだけ許ゆるす。scheme以降いこうのUnicode文字もじを正規化せいきかしない。相対そうたいpath・空文字くうもじをabsolute locatorとして受うけ付つけない。これはhost内部ないぶlocatorの境界きょうかいであり、HTTPのauthorityなどscheme固有こゆうの妥当性だとうせいや到達可能性とうたつかのうせいを保証ほしょうしない。外部がいぶURLとして使用しようするadapterはその用途ようとのURI/IRI検査けんさを行おこなう。schemeの根拠こんきょは RFC 3986 §3.1、Unicodeを含ふくむ識別子しきべつしとURIの区別くべつは RFC 3987。
SchemaRef.digestは、schemaの正規せいきdescriptorを対象たいしょうとする。正規せいきdescriptorはpackage名めい、revision、kind/variant/field定義ていぎ、意味上いみじょうのoperation署名しょめい、局所制約識別きょくしょせいやくしきべつを含ふくみ、source位置いち、documentation、cache、生成時刻せいせいじこくを含ふくまない。自己参照じこさんしょうとforeign schemaは(package, revision, typeName)の記号的参照きごうてきさんしょうとし、このdescriptor内ないへ相互そうごのdigestを再帰的さいきてきに埋うめ込こまない。実際じっさいに使用しようするforeign digestはProfileの解決済かいけつずみ一覧いちらんで固定こていして検査けんさする。これによりDocとMathが互たがいの型かたを参照さんしょうしてもhashの固定点こていてんを計算けいさんする必要ひつようはない。
型かたのconstraintsは実行順じっこうじゅんではなく、名前なまえで識別しきべつする局所制約きょくしょせいやくの集合しゅうごうである。空から・重複ちょうふくの識別子しきべつしを拒否きょひし、canonical descriptorへ変換へんかんするときにUnicode scalar順じゅんのarrayへ並ならべる。fieldやordered-choiceの意味順いみじゅんを持もつarrayとは区別くべつする。
descriptorの正規化せいきかデータはNull/Bool/非負ひふInteger/Text/Array/Objectだけを使つかう。JSONをdigest入力にゅうりょくとして使つかう場合ばあい、object keyをUnicode scalar順じゅんにsortし、array順じゅんを維持いじし、空白くうはくなし、UTF-8、引用符いんようふとbackslashをescapeし、U+0000..001Fは小文字こもじhexの\u00xxでescapeし、それ以外いがいのscalarは直接ちょくせつUTF-8とする。整数せいすうは先頭せんとうzeroなし。float、負数ふすう、surrogate、重複ちょうふくkeyは禁止きんし。hash入力にゅうりょくはASCII NEPL3-SCHEMA-1 + 1byte zero + このcanonical JSON。
Grammar packageの意味いみdigestはschema digestと、source位置いちを除のぞいたreader/binding/style/shape/provider要件ようけんの正規せいきdescriptorに対たいして、同おなじ規則きそくでdomain separatorを NEPL3-PACKAGE-1 として計算けいさんする。局所きょくしょkind IDはkind名めいのscalar順じゅんで割わり当あてる。field・宣言せんげん・ordered-choiceの意味上いみじょうの順序じゅんじょはarrayとして保存ほぞんする。名前なまえで識別しきべつするsum/union/variantsのmap順じゅんには意味いみがなく、canonical JSONのkey sortで一致いっちさせる。variant payloadのfield順じゅんはarrayとして保存ほぞんする。fieldの順序交換じゅんじょこうかんはdigestを変かえ、variant mapのkey順じゅんだけの交換こうかんは変かえない。seedとcompile後ごのpackageは意味いみdigestを比較ひかくし、provenanceの違ちがいを意味不一致いみふいっちとしない。source artifactのdigestは別べつに記録きろくする。
wireの操作要求そうさようきゅうは、解決済かいけつずみProfileの全ぜんSchemaRefとprovider revisionを含ふくめてcache keyを作つくる。URIやsnapshot所属しょぞくを除のぞいてよいのは明示的めいじてきな意味値いみちだけのcacheであり、診断しんだん/editor結果けっかのcacheにはsource identityとrevisionが必要ひつよう。
Package意味正規形いみせいきけい
実装じっそうのCheckedLanguagePackage::semantic_jsonはcategories、extensions、forms、leaves、modes、namespaces、payloadSchemas、reader、recovery、root、schemaのkeyを持もつcanonical JSONを返かえす。Category/Mode/Namespace/Extensionは名前順なまえじゅん、Formはcategoryとspelling順じゅん、Leafはcategoryとcanonical token-kind ID順じゅん、payloadSchemasはpackage/revision/digest順じゅんに並ならべる。重複ちょうふくするpayload SchemaRefは拒否きょひする。各かくレコードのpayload field順じゅんはinterfaces/engine.jsonの対応型たいおうがたに従したがう。ただしread/binding参照さんしょうは下記かきの式しきへ展開てんかいし、provenanceとarenaそのものは含ふくめない。styleにはschema/nameに加くわえてfallback roleも含ふくめる。
readとbindingの式しきはvariant名めいを先頭せんとうとするarrayで、variantのpayloadはnative公開型こうかいがたのfield順じゅんとする。ListOfは["ListOf",cons,nil,element]、Builtinは["Builtin",reader,kind,tokenKind]とする。kindは[SchemaRef,localKind]、operationは[SchemaRef,name]、styleは[selector,SchemaRef,name,fallback]である。modeは[name,skipReaders,takePairs]、formは[category,spelling,kind,fields,binding,styles]、leafは[category,kind,tokenKind,payloadType,binding,styles]とする。field、skip/take、choice/seq、bindingの子こ、styleの各列かくれつは意味順いみじゅんを保存ほぞんする。
readerは全名前付ぜんなまえつきruleを名前順なまえじゅんにたどり、直接ちょくせつDAGの共有きょうゆうを出現しゅつげんごとに展開てんかいしたpostorder arenaへ置換ちかんしたうえで、ReaderPlanの既存きそんcanonical descriptor形式けいしきを使つかう。rule名めいでのRefは展開てんかいしない。名前付なまえつきruleは未使用みしようでも公開宣言こうかいせんげんとして残のこす。匿名とくめいの未到達みとうたつarena entryは意味正規形いみせいきけいに含ふくめないが、package検査けんさはその不正参照ふせいさんしょう・cycleも拒否きょひする。ReadSpec/Bindingも使用元しようもとから展開てんかいし、匿名とくめいentryの共有きょうゆう・配置はいち・未到達収納みとうたつしゅうのうの差さを除のぞく。巨大きょだいな展開てんかいは共通予算きょうつうよさんでStoppedを返かえし、recursive stackに依存いぞんしない。
この正規形せいきけいは実行上じっこうじょうの任意にんいの等価性とうかせいを証明しょうめいするものではない。例たとえば異ことなるreader式しきへの代数的書換だいすうてきかきかえを同一視どういつししない。providerの要求署名ようきゅうしょめいはpackageへ含ふくめるが、hostの実装じっそうartifact identityは下記かきの解析かいせきProfileへ含ふくめる。packageの出自しゅつじを持もつeditor結果けっかはこの意味いみdigestだけでcacheしない。
recoveryは [defaultUnexpected,rules] とし、ruleはcategory順じゅんの [category,unexpected,synchronization]、同期列どうきれつは宣言順せんげんじゅんの [ancestorCategory,kind,spellingOrNull] とする。回復方針かいふくほうしんも実行挙動じっこうきょどうであり、順序じゅんじょやstrategyの変更へんこうを意味いみidentityへ反映はんえいする。
具体実行ぐたいじっこうidentity
継続けいぞくのarena indexと出自しゅつじの参照先さんしょうさきを固定こていするため、packageは意味いみidentityとは別べつにexecutionDigestを持もつ。hashは NEPL3-PACKAGE-EXECUTION-1 + zero byte + 具体実行ぐたいじっこうcanonical JSON とする。意味正規形いみせいきけいに加くわえ、元もとのReaderPlan descriptor、ReadSpec/Bindingの全ぜんarenaと直接参照ちょくせつさんしょうID、form/leaf等とうの宣言配置せんげんはいち、宣言せんげんのOrigin参照さんしょう、全ぜんprovenance source identity/URI、Origin/sourceMap tableを含ふくめる。sourceのbytesは検査済けんさずみsnapshot digestで固定こていする。意味上等いみじょうひとしいarena再配置さいはいちやgrammar source位置いちだけの変更へんこうでも、古ふるいframeや診断しんだんoriginを再利用さいりようしない。
EntryContextはpackage意味いみidentityに加くわえてProfile内ないのaliasを保持ほじする。同おなじpackageを異ことなるcategory-mode overrideで複数登録ふくすうとうろくできるため、packageから最初さいしょのaliasを逆引ぎゃくびきしてはならない。NodeSelectionのform/leaf/read/binding indexはそのaliasが指さすexecutionDigestの実じつtableに属ぞくする。再開さいかいおよび後段こうだんでの利用時りようじに具体ぐたいdigestを照合しょうごうし、意味いみdigestが一致いっちする別配置べつはいちへ勝手かってに差さし替かえない。
2. native値ちとwire値ち
型名中かためいちゅうのU64/Bytes32等とうの有限ゆうげんprimitiveと、任意精度にんいせいどNatural/Integerを区別くべつする。wire sourceはopaque SourceId/revision/digestを使つかう。同おなじIDをbundle内ない・操作間そうさかんの対応たいおうづけに使用しようし、URIやnative allocation addressへ置おき換かえない。同おなじURI/revision/byte列れつを持もつ独立文書どくりつぶんしょもSourceIdが異ことなれば別べつsnapshotである。r3のURI-based bijectionは、この場合ばあいにspec02の宣言同一性せんげんどういつせいを失うしなうためr4で訂正ていせいした。
native node indexはallocationごとのIDでもよい。wire bundleではrootからfield順じゅんに訪問ほうもんした最初さいしょの出現順しゅつげんじゅんで連番れんばんにする。shared nodeは二回目以降にかいめいこうreferenceを使つかう。source tableはSourceIdのUnicode scalar順じゅん、revisionの数値順すうちじゅん、digestのbyte順じゅんとし、schema tableはpackage/revision/digest順じゅん。Originの親参照おやさんしょうはDAGを検査けんさし、payload nodeとorigin nodeのID空間くうかんを分わける。SourceIdはこのnode index再採番さいさいばんの対象たいしょうにしない。
NodeRefの訪問ほうもんはdepth-firstで、Childをその位置いち、Childrenを列れつの順じゅんにたどる。rootは0となり、全ぜんNodeRefを書かき換かえる。ForeignSyntaxはguest bundleで独立どくりつして再採番さいさいばんし、ForeignSyntax.rootもguestの0へ対応たいおうさせる。wire bundleは単一たんいつrootの到達閉包とうたつへいほうを表あらわすため、到達不能とうたつふのうnodeはUnreachableNodeで拒否きょひし、黙だまって破棄はきしない。native arenaの未使用みしようslotは許ゆるせるが、出力対象しゅつりょくたいしょうbundleへ含ふくめない。Missing/Unexpected/Unparsed等とうの回復構文かいふくこうぶんもrootから参照さんしょうして保持ほじする。
TokenRef、Token内ないのViewRef、OriginRef、EnvironmentEntry.idはそれぞれの所有しょゆうtableで宣言せんげんされたslotを指さし、このNodeRef再採番さいさいばんの対象たいしょうではない。これらのtableとbinding/resource/role/relation/triviaの列順れつじゅんは値あたいの一部いちぶとして保存ほぞんする。生成側せいせいがわはsource順じゅんまたは明示めいじした生成順せいせいじゅんでtableを作つくり、allocation address・hash map列挙順れっきょじゅんを宣言順せんげんじゅんへ使つかわない。したがって、node arenaだけを並ならべ替かえた同おなじ値あたいはwire byte一致いっちを要求ようきゅうするが、別べつtableの宣言順せんげんじゅんまで異ことなるgraphの同型性どうけいせいをこの規則きそくだけで証明しょうめいしたとは扱あつかわない。
ParseTreeのcontexts/recoveryも同おなじ所有しょゆうbundleのNodeRef対応表たいおうひょうで変換へんかんする。ForeignStep.nodeはそのstepをたどる直前ちょくぜんのbundle、NodeSelection.nodeとRecoveryEntry.nodeはpathの終点しゅうてんbundleに属ぞくする。contextsはhostを先頭せんとうとし、各かくbundle内ないの正準せいじゅんnode順じゅん・field順じゅんで出会であうforeign bundleをdepth-firstでたどった順じゅんに置おく。各かくcontextのselectionsは正準せいじゅんnode順じゅんとする。recoveryは同おなじbundle順じゅんの部分列ぶぶんれつで、各かくentriesは正準せいじゅんnode順じゅんとする。受信側じゅしんがわはこの順序じゅんじょと参照先さんしょうさきの意味検査いみけんさを両方行りょうほうおこない、古ふるいwrapper番号ばんごうだけを残のこした値あたいを拒否きょひする。packageのform/leaf/read/binding index、executionDigest、FactSetのopaque IDは構文こうぶんnode再採番さいさいばんの対象たいしょうではない。
coreのNodeMappingは所有しょゆうbundleの参照範囲さんしょうはんい・到達閉包とうたつへいほうと正準番号せいじゅんばんごうの対応たいおうを計算けいさんする。これは単独たんどくではschema・source・cycle・選択せんたくの検査済けんさずみproofではない。engineのParseTree型付かたつきadapterは解決済かいけつずみProfileによる静的選択せいてきせんたく・回復検査かいふくけんさに加くわえ、Dynamicの実じつprovider登録とうろく・固定こていshape・保存ほぞんchildContextsの整合せいごうを検査けんさし、core-owned FoundationValueCodecを介かいしてwireの実じつSyntaxBundle変換へんかんを使つかう。wireからengineへの依存いぞんは追加ついかしない。Dynamicのpackage indexやchildContextsを構文こうぶんnode番号ばんごうとして再配置さいはいちしない。この検査けんさはproviderの実行履歴じっこうりれきの認証にんしょうを代替だいたいせず、ParseTree codec成立せいりつからparse continuation全体ぜんたいのportable化かを推定すいていしない。Facts要求応答ようきゅうおうとうの型付かたつき包絡ほうらくはこの同おなじtree codecと、要求ようきゅうに束縛そくばくしたfacts権限検査けんげんけんさを使用しようする。
SyntaxBundle.sourceMapsも宣言順せんげんじゅんの列れつとして保存ほぞんする。そのSpanはopaque source identityとbyte rangeを持もち、NodeRef再採番さいさいばんで変化へんかしない。foreign bundleは独自どくじのsourceMaps/sourcesを持もつ。生成せいせいsnapshotの予約よやくidentityもhostが固定こていしてからnative/portable比較ひかくへ渡わたし、別実装べつじっそうが独自どくじにIDを発明はつめいして同一どういつbyte列れつを偽装ぎそうしない。
EnvironmentEntry.digestは NEPL3-ENVIRONMENT-1 + zero byte + canonical NDF(Environment record) のSHA-256とする。entry自身じしんのid/digestはhashへ入いれない。bindings/resourcesの列順れつじゅんとbinding中ちゅうのbundle局所きょくしょOriginRefはEnvironment値ちの一部いちぶである。Origin tableを再編さいへんするhostは参照さんしょうとdigestを共ともに更新こうしんし、別べつbundleへ同おなじ数値すうちOriginRefだけを移うつして同一環境どういつかんきょうとみなさない。環境かんきょうdigest一致いっちはoriginの実在じつざい・domain bindingの意味検査いみけんさを代替だいたいしない。
この値あたいは局所きょくしょtable参照さんしょうを含ふくむ内容ないようdigestであり、参照先さんしょうさきOriginの閉包へいほうdigestではない。別べつのOrigin tableで同おなじ番号ばんごうを使つかえば同おなじ内容ないようdigestになり得うる。reader・editor・診断しんだんのcache keyはEnvironmentEntry.digestだけでなく、ReaderContextのOrigin table・選択せんたくProfile・source bundleのidentityを固定こていする。出自しゅつじを持もつ結果けっかを別べつbundleへ再利用さいりようしない。originの再採番時さいさいばんじはbindingとEnvironmentEntry.digestに加くわえ、ForeignSyntax.environment.digestを同時どうじに更新こうしんする。
3. normal formとartifact
printの正規形せいきけいは各言語かくげんごのformal source表ひょうに従したがう。lossless再出力さいしゅつりょくはoriginal SourceSnapshotの抽出ちゅうしゅつであり、意味いみprinterと同一視どういつししない。sourceを持もたない値あたいにもprefix printerが使つかえる。
HTML/XML出力しゅつりょくはUTF-8、属性ぞくせいはnamespace URIとlocal nameのscalar順じゅんで出力しゅつりょくする。モデル不変条件章ふへんじょうけんしょうの文字集合もじしゅうごうを検査後けんさご、Textと属性値ぞくせいちの &、<、> を常つねに &、<、> へescapeする。これによりXML文字もじデータ中ちゅうの ]]> も直接出力ちょくせつしゅつりょくされない。属性値ぞくせいちは二重引用符にじゅういんようふで囲かこみ、" は " とする。TextのCRは 
、属性値ぞくせいちのTAB/LF/CRはそれぞれ 	、
、
 としてparse後ごの値あたいを保持ほじする。TextのTAB/LFはそのまま出だす。HTMLのbrはvoid、XMLでは自己閉じことじを使つかう。外部がいぶから任意にんいのnamespace URIを受うけ付つけない。MathML/SVGのnamespaceはserializerが固定値こていちを生成せいせいする。
pixelの完全一致かんぜんいっちはOS/font/browserに依存いぞんするため、このbackendの契約けいやくは安全あんぜんなDOM内容ないよう・構造こうぞう・宣言せんげんされたstyle/layout規則きそくとする。同おなじbackend revisionの固定こていassetから生成せいせいするmarkup byte列れつは決定的けっていてき。nativeとprocessの同実装経路どうじっそうけいろではbyte一致いっち、異ことなる独立実装どくりつじっそうではcanonical構造一致こうぞういっちと定義済ていぎずみ表示規則ひょうじきそくを検査けんさする。
4. limitsとproviderの互換ごかん
algorithmごとのwork消費量しょうひりょうは異ことなってよい。十分じゅうぶんな予算よさんでCompleteになった同おなじ入力にゅうりょくについて、意味正規形いみせいきけい・診断しんだんcode/対象範囲たいしょうはんい・解決先かいけつさきが一致いっちすることを要求ようきゅうする。片方かたほうだけが予算不足よさんふそくの場合ばあい、値あたいの不一致ふいっちと同おなじ扱あつかいをしない。ただしlimit違反いはんの無視むし、partialをCompleteにすること、hostへ制御せいぎょを返かえさないことは契約違反けいやくいはん。
同おなじ入力にゅうりょく・environment・source/resources・provider revision・budgetでの同おなじ実装じっそうの結果けっかは決定的けっていてき。外部がいぶclock、乱数らんすう、OS directory順じゅんなどに意味いみを依存いぞんさせない。