/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dexgen.dex.code;

import com.android.dexgen.rop.code.RegisterSpec;
import com.android.dexgen.rop.code.RegisterSpecList;
import com.android.dexgen.rop.code.RegisterSpecSet;
import com.android.dexgen.rop.code.SourcePosition;

/**
 * Pseudo-instruction which is used to hold a snapshot of the
 * state of local variable name mappings that exists immediately after
 * the instance in an instruction array.
 */
public final class LocalSnapshot extends ZeroSizeInsn {
    /** {@code non-null;} local state associated with this instance */
    private final RegisterSpecSet locals;

    /**
     * Constructs an instance. The output address of this instance is initially
     * unknown ({@code -1}).
     *
     * @param position {@code non-null;} source position
     * @param locals {@code non-null;} associated local variable state
     */
    public LocalSnapshot(SourcePosition position, RegisterSpecSet locals) {
        super(position);

        if (locals == null) {
            throw new NullPointerException("locals == null");
        }

        this.locals = locals;
    }

    /** {@inheritDoc} */
    @Override
    public DalvInsn withRegisterOffset(int delta) {
        return new LocalSnapshot(getPosition(), locals.withOffset(delta));
    }

    /** {@inheritDoc} */
    @Override
    public DalvInsn withRegisters(RegisterSpecList registers) {
        return new LocalSnapshot(getPosition(), locals);
    }

    /**
     * Gets the local state associated with this instance.
     *
     * @return {@code non-null;} the state
     */
    public RegisterSpecSet getLocals() {
        return locals;
    }

    /** {@inheritDoc} */
    @Override
    protected String argString() {
        return locals.toString();
    }

    /** {@inheritDoc} */
    @Override
    protected String listingString0(boolean noteIndices) {
        int sz = locals.size();
        int max = locals.getMaxSize();
        StringBuffer sb = new StringBuffer(100 + sz * 40);

        sb.append("local-snapshot");

        for (int i = 0; i < max; i++) {
            RegisterSpec spec = locals.get(i);
            if (spec != null) {
                sb.append("\n  ");
                sb.append(LocalStart.localString(spec));
            }
        }

        return sb.toString();
    }
}
