11using System . Collections . Generic ;
22using System . IO ;
3- using System . Text . Json ;
4- using System . Text . Json . Serialization ;
3+
4+ using SimpleJSON ;
55
66using TextMateSharp . Grammars . Resources ;
77
88namespace TextMateSharp . Grammars
99{
1010 public class Engines
1111 {
12- [ JsonPropertyName ( "engines" ) ]
1312 public string VsCode { get ; set ; }
1413 }
1514
1615 public class Scripts
1716 {
18- [ JsonPropertyName ( "update-grammar" ) ]
1917 public string UpdateGrammar { get ; set ; }
2018 }
2119
2220 public class Language
2321 {
24- [ JsonPropertyName ( "id" ) ]
2522 public string Id { get ; set ; }
26- [ JsonPropertyName ( "extensions" ) ]
2723 public List < string > Extensions { get ; set ; }
28- [ JsonPropertyName ( "aliases" ) ]
2924 public List < string > Aliases { get ; set ; }
30- [ JsonPropertyName ( "configuration" ) ]
3125 public string ConfigurationFile { get ; set ; }
3226 public LanguageConfiguration Configuration { get ; set ; }
33-
34- // May be null
35- [ JsonPropertyName ( "mimetypes" ) ]
3627 public List < string > MimeTypes { get ; set ; }
3728
3829 public override string ToString ( )
@@ -46,62 +37,188 @@ public override string ToString()
4637
4738 public class Grammar
4839 {
49- [ JsonPropertyName ( "language" ) ]
5040 public string Language { get ; set ; }
51- [ JsonPropertyName ( "scopeName" ) ]
5241 public string ScopeName { get ; set ; }
53- [ JsonPropertyName ( "path" ) ]
5442 public string Path { get ; set ; }
5543 }
5644
5745 public class Snippet
5846 {
59- [ JsonPropertyName ( "language" ) ]
6047 public string Language { get ; set ; }
61- [ JsonPropertyName ( "path" ) ]
6248 public string Path { get ; set ; }
6349 }
6450
6551 public class Contributes
6652 {
67- [ JsonPropertyName ( "languages" ) ]
6853 public List < Language > Languages { get ; set ; }
69- [ JsonPropertyName ( "grammars" ) ]
7054 public List < Grammar > Grammars { get ; set ; }
71- [ JsonPropertyName ( "snippets" ) ]
7255 public List < Snippet > Snippets { get ; set ; }
7356 }
7457
7558 public class Repository
7659 {
77- [ JsonPropertyName ( "type" ) ]
7860 public string Type { get ; set ; }
79- [ JsonPropertyName ( "url" ) ]
8061 public string Url { get ; set ; }
8162 }
8263
8364 public class GrammarDefinition
8465 {
85- [ JsonPropertyName ( "name" ) ]
8666 public string Name { get ; set ; }
87- [ JsonPropertyName ( "displayName" ) ]
8867 public string DisplayName { get ; set ; }
89- [ JsonPropertyName ( "description" ) ]
9068 public string Description { get ; set ; }
91- [ JsonPropertyName ( "version" ) ]
9269 public string Version { get ; set ; }
93- [ JsonPropertyName ( "publisher" ) ]
9470 public string Publisher { get ; set ; }
95- [ JsonPropertyName ( "license" ) ]
9671 public string License { get ; set ; }
97- [ JsonPropertyName ( "engines" ) ]
9872 public Engines Engines { get ; set ; }
99- [ JsonPropertyName ( "scripts" ) ]
10073 public Scripts Scripts { get ; set ; }
101- [ JsonPropertyName ( "contributes" ) ]
10274 public Contributes Contributes { get ; set ; }
103- [ JsonPropertyName ( "repository" ) ]
10475 public Repository Repository { get ; set ; }
10576 public LanguageSnippets LanguageSnippets { get ; set ; }
77+
78+ public static GrammarDefinition Parse ( Stream stream )
79+ {
80+ using ( StreamReader reader = new StreamReader ( stream ) )
81+ {
82+ return Parse ( reader . ReadToEnd ( ) ) ;
83+ }
84+ }
85+
86+ public static GrammarDefinition Parse ( string jsonContent )
87+ {
88+ JSONNode json = JSON . Parse ( jsonContent ) ;
89+ if ( json == null )
90+ return null ;
91+
92+ var definition = new GrammarDefinition
93+ {
94+ Name = json [ "name" ] ,
95+ DisplayName = json [ "displayName" ] ,
96+ Description = json [ "description" ] ,
97+ Version = json [ "version" ] ,
98+ Publisher = json [ "publisher" ] ,
99+ License = json [ "license" ]
100+ } ;
101+
102+ if ( json [ "engines" ] != null && ! json [ "engines" ] . IsNull )
103+ {
104+ definition . Engines = new Engines
105+ {
106+ VsCode = json [ "engines" ] [ "vscode" ]
107+ } ;
108+ }
109+
110+ if ( json [ "scripts" ] != null && ! json [ "scripts" ] . IsNull )
111+ {
112+ definition . Scripts = new Scripts
113+ {
114+ UpdateGrammar = json [ "scripts" ] [ "update-grammar" ]
115+ } ;
116+ }
117+
118+ if ( json [ "repository" ] != null && ! json [ "repository" ] . IsNull )
119+ {
120+ definition . Repository = new Repository
121+ {
122+ Type = json [ "repository" ] [ "type" ] ,
123+ Url = json [ "repository" ] [ "url" ]
124+ } ;
125+ }
126+
127+ if ( json [ "contributes" ] != null && ! json [ "contributes" ] . IsNull )
128+ {
129+ definition . Contributes = ParseContributes ( json [ "contributes" ] ) ;
130+ }
131+
132+ return definition ;
133+ }
134+
135+ private static Contributes ParseContributes ( JSONNode node )
136+ {
137+ var contributes = new Contributes ( ) ;
138+
139+ if ( node [ "languages" ] != null && node [ "languages" ] . IsArray )
140+ {
141+ contributes . Languages = new List < Language > ( ) ;
142+ foreach ( JSONNode langNode in node [ "languages" ] . Children )
143+ {
144+ var language = new Language
145+ {
146+ Id = langNode [ "id" ] ,
147+ ConfigurationFile = GetNullableString ( langNode [ "configuration" ] )
148+ } ;
149+
150+ if ( langNode [ "extensions" ] != null && langNode [ "extensions" ] . IsArray )
151+ {
152+ language . Extensions = new List < string > ( ) ;
153+ foreach ( JSONNode ext in langNode [ "extensions" ] . Children )
154+ {
155+ language . Extensions . Add ( ext . Value ) ;
156+ }
157+ }
158+
159+ if ( langNode [ "aliases" ] != null && langNode [ "aliases" ] . IsArray )
160+ {
161+ language . Aliases = new List < string > ( ) ;
162+ foreach ( JSONNode alias in langNode [ "aliases" ] . Children )
163+ {
164+ language . Aliases . Add ( alias . Value ) ;
165+ }
166+ }
167+
168+ if ( langNode [ "mimetypes" ] != null && langNode [ "mimetypes" ] . IsArray )
169+ {
170+ language . MimeTypes = new List < string > ( ) ;
171+ foreach ( JSONNode mime in langNode [ "mimetypes" ] . Children )
172+ {
173+ language . MimeTypes . Add ( mime . Value ) ;
174+ }
175+ }
176+
177+ contributes . Languages . Add ( language ) ;
178+ }
179+ }
180+
181+ if ( node [ "grammars" ] != null && node [ "grammars" ] . IsArray )
182+ {
183+ contributes . Grammars = new List < Grammar > ( ) ;
184+ foreach ( JSONNode grammarNode in node [ "grammars" ] . Children )
185+ {
186+ contributes . Grammars . Add ( new Grammar
187+ {
188+ Language = grammarNode [ "language" ] ,
189+ ScopeName = grammarNode [ "scopeName" ] ,
190+ Path = grammarNode [ "path" ]
191+ } ) ;
192+ }
193+ }
194+
195+ if ( node [ "snippets" ] != null && node [ "snippets" ] . IsArray )
196+ {
197+ contributes . Snippets = new List < Snippet > ( ) ;
198+ foreach ( JSONNode snippetNode in node [ "snippets" ] . Children )
199+ {
200+ contributes . Snippets . Add ( new Snippet
201+ {
202+ Language = snippetNode [ "language" ] ,
203+ Path = snippetNode [ "path" ]
204+ } ) ;
205+ }
206+ }
207+
208+ return contributes ;
209+ }
210+
211+ /// <summary>
212+ /// Helper to convert SimpleJSON string values to null when empty.
213+ /// SimpleJSON returns "" for missing keys, but we need null for proper semantics.
214+ /// </summary>
215+ private static string GetNullableString ( JSONNode node )
216+ {
217+ if ( node == null || node . IsNull )
218+ return null ;
219+
220+ string value = node . Value ;
221+ return string . IsNullOrEmpty ( value ) ? null : value ;
222+ }
106223 }
107224}
0 commit comments