]> git.proxmox.com Git - mirror_edk2.git/blob - Tools/Source/GenBuild/org/tianocore/build/pcd/entity/Token.java
Modify PCD tool according to final PCD schema modification.
[mirror_edk2.git] / Tools / Source / GenBuild / org / tianocore / build / pcd / entity / Token.java
1 /** @file
2 Token class.
3
4 This module contains all classes releted to PCD token.
5
6 Copyright (c) 2006, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16 package org.tianocore.build.pcd.entity;
17
18 import java.util.ArrayList;
19 import java.util.List;
20 import java.util.UUID;
21 import java.util.Map;
22 import java.util.HashMap;
23
24 import org.tianocore.build.pcd.action.ActionMessage;
25 import org.tianocore.build.pcd.exception.EntityException;
26
27 /** This class is to descript a PCD token object. The information of a token mainly
28 comes from MSA, SPD and setting produced by platform developer.
29 **/
30 public class Token {
31 ///
32 /// Enumeration macro defintion for PCD type.
33 /// BUGBUG: Not use upcase charater is to facility for reading. It may be changed
34 /// in coding review.
35 public enum PCD_TYPE {FEATURE_FLAG, FIXED_AT_BUILD, PATCHABLE_IN_MODULE, DYNAMIC,
36 DYNAMIC_EX, UNKNOWN}
37
38 ///
39 /// Enumeration macro definition for datum type. All type mainly comes from ProcessBind.h.
40 /// Wizard maybe expand this type as "int, unsigned int, short, unsigned short etc" in
41 /// prompt dialog.
42 ///
43 public enum DATUM_TYPE {UINT8, UINT16, UINT32, UINT64, BOOLEAN, POINTER, UNKNOWN}
44
45 ///
46 /// Enumeration macor defintion for usage of PCD
47 ///
48 public enum PCD_USAGE {ALWAYS_PRODUCED, ALWAYS_CONSUMED, SOMETIMES_PRODUCED,
49 SOMETIMES_CONSUMED, UNKNOWN}
50
51 ///
52 /// cName is to identify a PCD entry and will be used for generating autogen.h/autogen.c.
53 /// cName will be defined in MSA, SPD and FPD, can be regarded as primary key with token space guid.
54 ///
55 public String cName;
56
57 ///
58 /// Token space name is the guid defined by token itself in package or module level. This
59 /// name mainly for DynamicEx type. For other PCD type token, his token space name is the
60 /// assignedtokenSpaceName as follows.
61 /// tokenSpaceName is defined in MSA, SPD, FPD, can be regarded as primary key with cName.
62 ///
63 public UUID tokenSpaceName;
64
65 ///
66 /// tokenNumber is allocated by platform. tokenNumber indicate an index for this token in
67 /// platform token space.
68 /// tokenNumber is defined in SPD, FPD.
69 ///
70 public int tokenNumber;
71
72 ///
73 /// All supported PCD type, this value can be retrieved from SPD
74 /// Currently, only record all PCD type for this token in FPD file.
75 ///
76 public List<PCD_TYPE> supportedPcdType;
77
78 ///
79 /// If the token's item type is Dynamic or DynamicEx type, isDynamicPCD
80 /// is true.
81 ///
82 public boolean isDynamicPCD;
83
84 ///
85 /// datumSize is to descript the fix size or max size for this token.
86 /// datumSize is defined in SPD.
87 ///
88 public int datumSize;
89
90 ///
91 /// datum type is to descript what type can be expressed by a PCD token.
92 /// For same PCD used in different module, the datum type should be unique.
93 /// So it belong memeber to Token class.
94 ///
95 public DATUM_TYPE datumType;
96
97 ///
98 /// skuData contains all value for SkuNumber of token.
99 /// This field is for Dynamic or DynamicEx type PCD,
100 ///
101 public List<SkuInstance> skuData;
102
103 ///
104 /// consumers array record all module private information who consume this PCD token.
105 ///
106 public Map<String, UsageInstance> consumers;
107
108 public Token(String cName, UUID tokenSpaceName) {
109 UUID nullUUID = new UUID(0, 0);
110
111 this.cName = cName;
112 this.tokenSpaceName = (tokenSpaceName == null) ? nullUUID : tokenSpaceName;
113 this.tokenNumber = 0;
114 this.datumType = DATUM_TYPE.UNKNOWN;
115 this.datumSize = -1;
116 this.skuData = new ArrayList<SkuInstance>();
117
118 this.consumers = new HashMap<String, UsageInstance>();
119 this.supportedPcdType = new ArrayList<PCD_TYPE>();
120 }
121
122 /**
123 updateSupportPcdType
124
125 SupportPcdType should be gotten from SPD file actually, but now it just
126 record all PCD type for this token in FPD file.
127
128 @param pcdType new PCD type found in FPD file for this token.
129 **/
130 public void updateSupportPcdType(PCD_TYPE pcdType) {
131 int index = 0;
132 boolean found = false;
133 for (index = 0; index < this.supportedPcdType.size(); index ++) {
134 if (this.supportedPcdType.get(index) == pcdType) {
135 found = true;
136 break;
137 }
138 }
139 if (!found) {
140 this.supportedPcdType.add(pcdType);
141 }
142 }
143
144 /**
145 Judge whether pcdType is belong to dynamic type. Dynamic type includes
146 DYNAMIC and DYNAMIC_EX.
147
148 @param pcdType
149
150 @return boolean
151 */
152 public static boolean isDynamic(PCD_TYPE pcdType) {
153 if ((pcdType == PCD_TYPE.DYNAMIC ) ||
154 (pcdType == PCD_TYPE.DYNAMIC_EX)) {
155 return true;
156 }
157
158 return false;
159 }
160
161 /**
162 Use "TokencName + "-" + SpaceTokenName" as primary key when adding token into database
163
164 @param cName Token name.
165 @param tokenSpaceName The token space guid defined in MSA or SPD
166 @param platformtokenSpaceName The token space guid for current platform token space,
167
168 @return primary key for this token in token database.
169 **/
170 public static String getPrimaryKeyString(String cName, UUID tokenSpaceName) {
171 UUID nullUUID = new UUID(0, 0);
172
173 if (tokenSpaceName == null) {
174 return cName + "_" + nullUUID.toString().replace('-', '_');
175 } else {
176 return cName + "_" + tokenSpaceName.toString().replace('-', '_');
177 }
178 }
179
180 /**
181 If skudata list contains more than one data, then Sku mechanism is enable.
182
183 @return boolean
184 */
185 public boolean isSkuEnable() {
186 if (this.skuData.size() > 1) {
187 return true;
188 }
189 return false;
190 }
191
192 /**
193 Get the token primary key in token database.
194
195 @return String
196 */
197 public String getPrimaryKeyString () {
198 return Token.getPrimaryKeyString(cName, tokenSpaceName);
199 }
200
201 /**
202 Judge datumType is valid
203
204 @param type The datumType want to be judged.
205
206 @retval TRUE - The type is valid.
207 @retval FALSE - The type is invalid.
208 **/
209 public static boolean isValiddatumType(DATUM_TYPE type) {
210 if ((type.ordinal() < DATUM_TYPE.UINT8.ordinal() ) ||
211 (type.ordinal() > DATUM_TYPE.POINTER.ordinal())) {
212 return false;
213 }
214 return true;
215 }
216
217 /**
218 Judge pcdType is valid
219
220 @param type The PCdType want to be judged.
221
222 @retval TRUE - The type is valid.
223 @retval FALSE - The type is invalid.
224 **/
225 public static boolean isValidpcdType(PCD_TYPE type) {
226 if ((type.ordinal() < PCD_TYPE.FEATURE_FLAG.ordinal() ) ||
227 (type.ordinal() > PCD_TYPE.DYNAMIC_EX.ordinal())) {
228 return false;
229 }
230 return true;
231 }
232
233 /**
234 Add an usage instance for token
235
236 @param usageInstance The usage instance
237
238 @retval TRUE - Success to add usage instance.
239 @retval FALSE - Fail to add usage instance
240 **/
241 public boolean addUsageInstance(UsageInstance usageInstance)
242 throws EntityException {
243 String exceptionStr;
244
245 if (isUsageInstanceExist(usageInstance.moduleName,
246 usageInstance.moduleGUID,
247 usageInstance.packageName,
248 usageInstance.packageGUID,
249 usageInstance.arch,
250 usageInstance.version)) {
251 exceptionStr = String.format("PCD %s for module %s has already exist in database, Please check all PCD build entries "+
252 "in modules PcdPeim in <ModuleSA> to make sure no duplicated definitions!",
253 usageInstance.parentToken.cName,
254 usageInstance.moduleName);
255 throw new EntityException(exceptionStr);
256 }
257
258 consumers.put(usageInstance.getPrimaryKey(), usageInstance);
259 return true;
260 }
261
262 /**
263 Judge whether exist an usage instance for this token
264
265 @param moduleName the name of module
266 @param moduleGuid the GUID name of modules
267 @param packageName the name of package contains this module
268 @param packageGuid the GUID name of package contains this module
269 @param arch the architecture string
270 @param version the version string
271
272 @return boolean whether exist an usage instance for this token.
273 */
274 public boolean isUsageInstanceExist(String moduleName,
275 UUID moduleGuid,
276 String packageName,
277 UUID packageGuid,
278 String arch,
279 String version) {
280 String keyStr = UsageInstance.getPrimaryKey(moduleName,
281 moduleGuid,
282 packageName,
283 packageGuid,
284 arch,
285 version);
286 return (consumers.get(keyStr) != null);
287 }
288
289 /**
290 Get the PCD_TYPE according to the string of PCD_TYPE
291
292 @param pcdTypeStr The string of PCD_TYPE
293
294 @return PCD_TYPE
295 **/
296 public static PCD_TYPE getpcdTypeFromString(String pcdTypeStr) {
297 if (pcdTypeStr == null) {
298 return PCD_TYPE.UNKNOWN;
299 }
300
301 if (pcdTypeStr.equalsIgnoreCase("FEATURE_FLAG")) {
302 return PCD_TYPE.FEATURE_FLAG;
303 } else if (pcdTypeStr.equalsIgnoreCase("FIXED_AT_BUILD")) {
304 return PCD_TYPE.FIXED_AT_BUILD;
305 } else if (pcdTypeStr.equalsIgnoreCase("PATCHABLE_IN_MODULE")) {
306 return PCD_TYPE.PATCHABLE_IN_MODULE;
307 } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC")) {
308 return PCD_TYPE.DYNAMIC;
309 } else if (pcdTypeStr.equalsIgnoreCase("DYNAMIC_EX")) {
310 return PCD_TYPE.DYNAMIC_EX;
311 } else {
312 return PCD_TYPE.UNKNOWN;
313 }
314 }
315
316 /**
317 Get the string of given datumType. This string will be used for generating autogen files
318
319 @param datumType Given datumType
320
321 @return The string of datum type.
322 **/
323 public static String getStringOfdatumType(DATUM_TYPE datumType) {
324 switch (datumType) {
325 case UINT8:
326 return "UINT8";
327 case UINT16:
328 return "UINT16";
329 case UINT32:
330 return "UINT32";
331 case UINT64:
332 return "UINT64";
333 case POINTER:
334 return "POINTER";
335 case BOOLEAN:
336 return "BOOLEAN";
337 }
338 return "UNKNOWN";
339 }
340
341 /**
342 Get the datumType according to a string.
343
344 @param datumTypeStr The string of datumType
345
346 @return DATUM_TYPE
347 **/
348 public static DATUM_TYPE getdatumTypeFromString(String datumTypeStr) {
349 if (datumTypeStr.equalsIgnoreCase("UINT8")) {
350 return DATUM_TYPE.UINT8;
351 } else if (datumTypeStr.equalsIgnoreCase("UINT16")) {
352 return DATUM_TYPE.UINT16;
353 } else if (datumTypeStr.equalsIgnoreCase("UINT32")) {
354 return DATUM_TYPE.UINT32;
355 } else if (datumTypeStr.equalsIgnoreCase("UINT64")) {
356 return DATUM_TYPE.UINT64;
357 } else if (datumTypeStr.equalsIgnoreCase("VOID*")) {
358 return DATUM_TYPE.POINTER;
359 } else if (datumTypeStr.equalsIgnoreCase("BOOLEAN")) {
360 return DATUM_TYPE.BOOLEAN;
361 }
362 return DATUM_TYPE.UNKNOWN;
363 }
364
365 /**
366 Get string of given pcdType
367
368 @param pcdType The given PcdType
369
370 @return The string of PCD_TYPE.
371 **/
372 public static String getStringOfpcdType(PCD_TYPE pcdType) {
373 switch (pcdType) {
374 case FEATURE_FLAG:
375 return "FEATURE_FLAG";
376 case FIXED_AT_BUILD:
377 return "FIXED_AT_BUILD";
378 case PATCHABLE_IN_MODULE:
379 return "PATCHABLE_IN_MODULE";
380 case DYNAMIC:
381 return "DYNAMIC";
382 case DYNAMIC_EX:
383 return "DYNAMIC_EX";
384 }
385 return "UNKNOWN";
386 }
387
388 /**
389 Get the PCD_USAGE according to a string
390
391 @param usageStr The string of PCD_USAGE
392
393 @return The PCD_USAGE
394 **/
395 public static PCD_USAGE getUsageFromString(String usageStr) {
396 if (usageStr == null) {
397 return PCD_USAGE.UNKNOWN;
398 }
399
400 if (usageStr.equalsIgnoreCase("ALWAYS_PRODUCED")) {
401 return PCD_USAGE.ALWAYS_PRODUCED;
402 } else if (usageStr.equalsIgnoreCase("SOMETIMES_PRODUCED")) {
403 return PCD_USAGE.SOMETIMES_PRODUCED;
404 } else if (usageStr.equalsIgnoreCase("ALWAYS_CONSUMED")) {
405 return PCD_USAGE.ALWAYS_CONSUMED;
406 } else if (usageStr.equalsIgnoreCase("SOMETIMES_CONSUMED")) {
407 return PCD_USAGE.SOMETIMES_CONSUMED;
408 }
409
410 return PCD_USAGE.UNKNOWN;
411 }
412
413 /**
414 Get the string of given PCD_USAGE
415
416 @param usage The given PCD_USAGE
417
418 @return The string of PDC_USAGE.
419 **/
420 public static String getStringOfUsage(PCD_USAGE usage) {
421 switch (usage) {
422 case ALWAYS_PRODUCED:
423 return "ALWAYS_PRODUCED";
424 case ALWAYS_CONSUMED:
425 return "ALWAYS_CONSUMED";
426 case SOMETIMES_PRODUCED:
427 return "SOMETIMES_PRODUCED";
428 case SOMETIMES_CONSUMED:
429 return "SOMETIMES_CONSUMED";
430 }
431 return "UNKNOWN";
432 }
433
434 /**
435 Get the Defined datumType string for autogen. The string is for generating some MACROs in Autogen.h
436
437 @param datumType The given datumType
438
439 @return string of datum type for autogen.
440 **/
441 public static String GetAutogenDefinedatumTypeString(DATUM_TYPE datumType) {
442 switch (datumType) {
443
444 case UINT8:
445 return "8";
446 case UINT16:
447 return "16";
448 case BOOLEAN:
449 return "BOOL";
450 case POINTER:
451 return "PTR";
452 case UINT32:
453 return "32";
454 case UINT64:
455 return "64";
456 default:
457 return null;
458 }
459 }
460
461 /**
462 Get the datumType String for Autogen. This string will be used for generating defintions of PCD token in autogen
463
464 @param datumType The given datumType
465
466 @return string of datum type.
467 **/
468 public static String getAutogendatumTypeString(DATUM_TYPE datumType) {
469 switch (datumType) {
470 case UINT8:
471 return "UINT8";
472 case UINT16:
473 return "UINT16";
474 case UINT32:
475 return "UINT32";
476 case UINT64:
477 return "UINT64";
478 case POINTER:
479 return "VOID*";
480 case BOOLEAN:
481 return "BOOLEAN";
482 }
483 return null;
484 }
485
486 /**
487 Get the datumType string for generating some MACROs in autogen file of Library
488
489 @param datumType The given datumType
490
491 @return String of datum for genrating bit charater.
492 **/
493 public static String getAutogenLibrarydatumTypeString(DATUM_TYPE datumType) {
494 switch (datumType) {
495 case UINT8:
496 return "8";
497 case UINT16:
498 return "16";
499 case BOOLEAN:
500 return "Bool";
501 case POINTER:
502 return "Ptr";
503 case UINT32:
504 return "32";
505 case UINT64:
506 return "64";
507 default:
508 return null;
509 }
510 }
511
512 /**
513 UUID defined in Schems is object, this function is to tranlate this object
514 to UUID data.
515
516 @param uuidObj The object comes from schema.
517
518 @return The traslated UUID instance.
519 **/
520 public static UUID getGUIDFromSchemaObject(Object uuidObj) {
521 UUID uuid;
522 if (uuidObj.toString().equalsIgnoreCase("0")) {
523 uuid = new UUID(0,0);
524 } else {
525 uuid = UUID.fromString(uuidObj.toString());
526 }
527
528 return uuid;
529 }
530
531 public DynamicTokenValue getDefaultSku() {
532 DynamicTokenValue dynamicData;
533 int index;
534 for (index = 0; index < this.skuData.size(); index ++) {
535 if (skuData.get(index).id == 0) {
536 return skuData.get(index).value;
537 }
538 }
539
540 return null;
541 }
542 //
543 // BugBug: We need change this algorithm accordingly when schema is updated
544 // to support no default value.
545 //
546 public boolean hasDefaultValue () {
547 int value = 0;
548 boolean isInteger = true;
549 DynamicTokenValue dynamicValue = null;
550
551 if (this.isDynamicPCD) {
552 dynamicValue = getDefaultSku();
553 switch (dynamicValue.type) {
554 case HII_TYPE:
555 try {
556 value = Integer.decode(dynamicValue.hiiDefaultValue);
557 } catch (NumberFormatException nfEx) {
558 isInteger = false;
559 }
560
561 if (isInteger && (value == 0)) {
562 return false;
563 } else {
564 return true;
565 }
566
567 case VPD_TYPE:
568 return false;
569
570 case DEFAULT_TYPE:
571 try{
572 value = Integer.decode(dynamicValue.value);
573 } catch (NumberFormatException nfEx) {
574 isInteger = false;
575 }
576
577 if (isInteger && (value == 0)) {
578 return false;
579 } else {
580 return true;
581 }
582
583 }
584 }
585
586 return false;
587 }
588
589 //
590 // TODO: Need scott's confirmation
591 //
592 public boolean isStringType () {
593 String str = getDefaultSku().value;
594
595 if (datumType == Token.DATUM_TYPE.POINTER &&
596 str.startsWith("L\"") &&
597 str.endsWith("\"")) {
598 return true;
599 }
600
601 return false;
602 }
603
604 public String getStringTypeString () {
605 return getDefaultSku().value.substring(2, getDefaultSku().value.length() - 1);
606 }
607 }
608
609
610
611