1 /*******************************************************************************
2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.ctf
.core
.event
.types
;
15 import java
.util
.Collections
;
16 import java
.util
.LinkedList
;
17 import java
.util
.List
;
20 import org
.eclipse
.jdt
.annotation
.NonNull
;
21 import org
.eclipse
.linuxtools
.ctf
.core
.event
.scope
.IDefinitionScope
;
22 import org
.eclipse
.linuxtools
.ctf
.core
.event
.scope
.LexicalScope
;
24 import com
.google
.common
.base
.Joiner
;
25 import com
.google
.common
.collect
.ImmutableList
;
26 import com
.google
.common
.collect
.ImmutableMap
;
27 import com
.google
.common
.collect
.ImmutableMap
.Builder
;
30 * A CTF structure definition (similar to a C structure).
32 * A structure is similar to a C structure, it is a compound data type that
33 * contains other datatypes in fields. they are stored in an hashmap and indexed
34 * by names which are strings.
36 * TODO: move me to internal
39 * @author Matthew Khouzam
40 * @author Simon Marchi
42 public final class StructDefinition
extends ScopedDefinition
implements ICompositeDefinition
{
44 // ------------------------------------------------------------------------
46 // ------------------------------------------------------------------------
48 private final ImmutableList
<String
> fFieldNames
;
49 private final Definition
[] fDefinitions
;
50 private Map
<String
, Definition
> fDefinitionsMap
= null;
52 // ------------------------------------------------------------------------
54 // ------------------------------------------------------------------------
57 * *DEPRECATED* TODO: To remove once we break the API...
59 * Not marked with the annotation to not annoy callers using a List, which
60 * is still as valid with the new constructor. But the compiler gives an
61 * error even though a Iterable is a List too...
64 * the parent declaration
65 * @param definitionScope
67 * @param structFieldName
75 public StructDefinition(@NonNull StructDeclaration declaration
,
76 IDefinitionScope definitionScope
,
77 @NonNull String structFieldName
,
78 List
<String
> fieldNames
,
79 Definition
[] definitions
) {
80 this(declaration
, definitionScope
, structFieldName
, (Iterable
<String
>) fieldNames
, definitions
);
87 * the parent declaration
88 * @param definitionScope
90 * @param structFieldName
98 public StructDefinition(@NonNull StructDeclaration declaration
,
99 IDefinitionScope definitionScope
,
100 @NonNull String structFieldName
,
101 Iterable
<String
> fieldNames
,
102 Definition
[] definitions
) {
103 super(declaration
, definitionScope
, structFieldName
);
104 fFieldNames
= ImmutableList
.copyOf(fieldNames
);
105 fDefinitions
= definitions
;
106 if (fFieldNames
.isEmpty()) {
107 fDefinitionsMap
= Collections
.EMPTY_MAP
;
112 * Constructor This one takes the scope and thus speeds up definition
116 * the parent declaration
117 * @param definitionScope
120 * the scope of this variable
121 * @param structFieldName
129 public StructDefinition(@NonNull StructDeclaration declaration
,
130 IDefinitionScope definitionScope
, @NonNull LexicalScope scope
,
131 @NonNull String structFieldName
, @NonNull Iterable
<String
> fieldNames
, Definition
[] definitions
) {
132 super(declaration
, definitionScope
, structFieldName
, scope
);
133 fFieldNames
= ImmutableList
.copyOf(fieldNames
);
134 fDefinitions
= definitions
;
135 if (fFieldNames
.isEmpty()) {
136 fDefinitionsMap
= Collections
.EMPTY_MAP
;
140 // ------------------------------------------------------------------------
141 // Getters/Setters/Predicates
142 // ------------------------------------------------------------------------
145 public Definition
getDefinition(String fieldName
) {
146 if (fDefinitionsMap
== null) {
147 /* Build the definitions map */
148 Builder
<String
, Definition
> mapBuilder
= new ImmutableMap
.Builder
<>();
149 for (int i
= 0; i
< fFieldNames
.size(); i
++) {
150 if (fDefinitions
[i
] != null) {
151 mapBuilder
.put(fFieldNames
.get(i
), fDefinitions
[i
]);
154 fDefinitionsMap
= mapBuilder
.build();
156 return fDefinitionsMap
.get(fieldName
);
160 public List
<String
> getFieldNames() {
165 public StructDeclaration
getDeclaration() {
166 return (StructDeclaration
) super.getDeclaration();
169 // ------------------------------------------------------------------------
171 // ------------------------------------------------------------------------
174 public Definition
lookupDefinition(String lookupPath
) {
176 * The fields are created in order of appearance, so if a variant or
177 * sequence refers to a field that is after it, the field's definition
178 * will not be there yet in the hashmap.
180 int val
= fFieldNames
.indexOf(lookupPath
);
182 return fDefinitions
[val
];
184 String lookupUnderscored
= "_" + lookupPath
; //$NON-NLS-1$
185 val
= fFieldNames
.indexOf(lookupUnderscored
);
187 return fDefinitions
[val
];
193 public String
toString() {
194 StringBuilder builder
= new StringBuilder();
196 builder
.append("{ "); //$NON-NLS-1$
198 if (fFieldNames
!= null) {
199 List
<String
> fields
= new LinkedList
<>();
200 for (String field
: fFieldNames
) {
201 String appendee
= field
+ " = " + lookupDefinition(field
).toString(); //$NON-NLS-1$
202 fields
.add(appendee
);
204 Joiner joiner
= Joiner
.on(", ").skipNulls(); //$NON-NLS-1$
205 builder
.append(joiner
.join(fields
));
208 builder
.append(" }"); //$NON-NLS-1$
210 return builder
.toString();