1+ /* --------------------------------------------------------------------------------------------
2+ * Copyright (c) Microsoft Corporation. All Rights Reserved.
3+ * See 'LICENSE' in the project root for license information.
4+ * ------------------------------------------------------------------------------------------ */
5+ 'use strict' ;
6+
7+ import * as url from 'url' ;
8+ import * as https from 'https' ;
9+ import { ClientRequest } from 'http' ;
10+ import * as vscode from 'vscode' ;
11+ import * as fs from 'fs' ;
12+ import * as util from './common' ;
13+
14+ import * as Telemetry from './telemetry' ;
15+
16+ const userBucketMax : number = 100 ;
17+ const userBucketString : string = "CPP.UserBucket" ;
18+
19+ export function activate ( context : vscode . ExtensionContext ) : void {
20+ if ( context . globalState . get < number > ( userBucketString , - 1 ) == - 1 ) {
21+ let bucket : number = Math . floor ( Math . random ( ) * userBucketMax ) + 1 ; // Range is [1, userBucketMax].
22+ context . globalState . update ( userBucketString , bucket ) ;
23+ }
24+
25+ setInterval ( ( ) => {
26+ // Redownload occasionally to prevent an extra reload during long sessions.
27+ downloadCpptoolsJsonPkg ( ) ;
28+ } , 30 * 60 * 1000 ) ; // 30 minutes.
29+ }
30+
31+ // NOTE: Code is copied from DownloadPackage in packageManager.ts, but with ~75% fewer lines.
32+ function downloadCpptoolsJson ( urlString ) : Promise < void > {
33+ return new Promise < void > ( ( resolve , reject ) => {
34+ let parsedUrl : url . Url = url . parse ( urlString ) ;
35+ let request : ClientRequest = https . request ( {
36+ host : parsedUrl . host ,
37+ path : parsedUrl . path ,
38+ agent : util . GetHttpsProxyAgent ( ) ,
39+ rejectUnauthorized : vscode . workspace . getConfiguration ( ) . get ( "http.proxyStrictSSL" , true )
40+ } , ( response ) => {
41+ if ( response . statusCode == 301 || response . statusCode == 302 ) {
42+ let redirectUrl : string | string [ ] ;
43+ if ( typeof response . headers . location === "string" ) {
44+ redirectUrl = response . headers . location ;
45+ } else {
46+ redirectUrl = response . headers . location [ 0 ] ;
47+ }
48+ return resolve ( downloadCpptoolsJson ( redirectUrl ) ) ; // Redirect - download from new location
49+ }
50+ if ( response . statusCode != 200 ) {
51+ return reject ( ) ;
52+ }
53+ let downloadedBytes = 0 ; // tslint:disable-line
54+ let cppToolsJsonFile : fs . WriteStream = fs . createWriteStream ( util . getExtensionFilePath ( "cpptools.json" ) ) ;
55+ response . on ( 'data' , ( data ) => { downloadedBytes += data . length ; } ) ;
56+ response . on ( 'end' , ( ) => { cppToolsJsonFile . close ( ) ; } ) ;
57+ cppToolsJsonFile . on ( 'close' , ( ) => { resolve ( ) ; } ) ;
58+ response . on ( 'error' , ( error ) => { reject ( ) ; } ) ;
59+ response . pipe ( cppToolsJsonFile , { end : false } ) ;
60+ } ) ;
61+ request . on ( 'error' , ( error ) => { reject ( ) ; } ) ;
62+ request . end ( ) ;
63+ } ) ;
64+ }
65+
66+ export function downloadCpptoolsJsonPkg ( ) : Promise < void > {
67+ let hasError : boolean = false ;
68+ let telemetryProperties : { [ key : string ] : string } = { } ;
69+ return downloadCpptoolsJson ( "https://go.microsoft.com/fwlink/?linkid=852750" )
70+ . catch ( ( error ) => {
71+ // More specific error info is not likely to be helpful, and we get detailed download data from the initial install.
72+ hasError = true ;
73+ } )
74+ . then ( ( ) => {
75+ telemetryProperties [ 'success' ] = ( ! hasError ) . toString ( ) ;
76+ Telemetry . logDebuggerEvent ( "cpptoolsJsonDownload" , telemetryProperties ) ;
77+ } ) ;
78+ }
79+
80+ export function processCpptoolsJson ( cpptoolsString : string ) : Promise < void > {
81+ let cpptoolsObject : any = JSON . parse ( cpptoolsString ) ;
82+ let intelliSenseEnginePercentage : number = cpptoolsObject . intelliSenseEngine_default_percentage ;
83+
84+ if ( ! util . packageJson . extensionFolderPath . includes ( ".vscode-insiders" ) ) {
85+ let prevIntelliSenseEngineDefault : any = util . packageJson . contributes . configuration . properties [ "C_Cpp.intelliSenseEngine" ] . default ;
86+ if ( util . extensionContext . globalState . get < number > ( userBucketString , userBucketMax + 1 ) <= intelliSenseEnginePercentage ) {
87+ util . packageJson . contributes . configuration . properties [ "C_Cpp.intelliSenseEngine" ] . default = "Default" ;
88+ } else {
89+ util . packageJson . contributes . configuration . properties [ "C_Cpp.intelliSenseEngine" ] . default = "Tag Parser" ;
90+ }
91+ if ( prevIntelliSenseEngineDefault != util . packageJson . contributes . configuration . properties [ "C_Cpp.intelliSenseEngine" ] . default ) {
92+ return util . writeFileText ( util . getPackageJsonPath ( ) , util . getPackageJsonString ( ) ) ;
93+ }
94+ }
95+ }
0 commit comments