2 * Copyright (c) 2020 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.model.api;
10 import static java.util.Objects.requireNonNull;
12 import java.lang.invoke.MethodHandles;
13 import java.lang.invoke.VarHandle;
14 import java.util.AbstractList;
15 import java.util.ArrayDeque;
16 import java.util.Arrays;
17 import java.util.Deque;
18 import java.util.Iterator;
19 import java.util.Spliterator;
20 import org.eclipse.jdt.annotation.NonNull;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.opendaylight.yangtools.concepts.Immutable;
23 import org.opendaylight.yangtools.yang.common.QName;
25 final class PathFromRoot extends AbstractList<QName> implements Immutable {
26 private static final QName[] EMPTY_QNAMES = new QName[0];
27 private static final VarHandle QNAMES;
31 QNAMES = MethodHandles.lookup().findVarHandle(PathFromRoot.class, "qnames", QName[].class);
32 } catch (NoSuchFieldException | IllegalAccessException e) {
33 throw new ExceptionInInitializerError(e);
37 private final SchemaPath path;
39 @SuppressWarnings("unused")
40 private QName @Nullable [] qnames;
42 PathFromRoot(final SchemaPath path) {
43 this.path = requireNonNull(path);
47 public Iterator<QName> iterator() {
48 return Arrays.asList(qnames()).iterator();
52 public Spliterator<QName> spliterator() {
53 return Arrays.spliterator(qnames());
57 public QName get(final int index) {
58 return qnames()[index];
62 public boolean isEmpty() {
68 return qnames().length;
71 private QName @NonNull [] qnames() {
72 final QName[] local = (QName[]) QNAMES.getAcquire(this);
73 return local != null ? local : loadQNames();
76 private QName @NonNull [] loadQNames() {
77 final Deque<QName> tmp = new ArrayDeque<>();
78 for (QName qname : path.getPathTowardsRoot()) {
82 final QName[] result = tmp.toArray(EMPTY_QNAMES);
83 // We do not care about atomicity here
84 QNAMES.setRelease(this, result);