package org.chromium.sdk.internal.v8native; import java.util.Collections; import java.util.logging.Level; import java.util.logging.Logger; import org.chromium.sdk.DebugContext; import org.chromium.sdk.DebugEventListener; import org.chromium.sdk.RelayOk; import org.chromium.sdk.SyncCallback; import org.chromium.sdk.internal.ScriptBase; import org.chromium.sdk.internal.liveeditprotocol.LiveEditResult; import org.chromium.sdk.internal.protocolparser.JsonProtocolParseException; import org.chromium.sdk.internal.v8native.V8Helper.ScriptLoadCallback; import org.chromium.sdk.internal.v8native.protocol.input.ChangeLiveBody; import org.chromium.sdk.internal.v8native.protocol.input.SuccessCommandResponse; import org.chromium.sdk.internal.v8native.protocol.input.data.ScriptHandle; import org.chromium.sdk.internal.v8native.protocol.input.data.SomeHandle; import org.chromium.sdk.internal.v8native.protocol.output.ChangeLiveMessage; import org.chromium.sdk.internal.v8native.value.HandleManager; public class ScriptImpl extends ScriptBase<Long> { /** The class logger. */ private static final Logger LOGGER = Logger.getLogger(ScriptImpl.class.getName()); private final DebugSession debugSession; public ScriptImpl(Descriptor<Long> descriptor, DebugSession debugSession) { super(descriptor); this.debugSession = debugSession; } @Override public RelayOk setSourceOnRemote(String newSource, UpdateCallback callback, SyncCallback syncCallback) { V8CommandProcessor.V8HandlerCallback v8Callback = createScriptUpdateCallback(callback, false); return debugSession.sendMessageAsync(new ChangeLiveMessage(getId(), newSource, Boolean.FALSE), true, v8Callback, syncCallback); } @Override public RelayOk previewSetSource(String newSource, UpdateCallback callback, SyncCallback syncCallback) { V8CommandProcessor.V8HandlerCallback v8Callback = createScriptUpdateCallback(callback, true); return debugSession.sendMessageAsync(new ChangeLiveMessage(getId(), newSource, Boolean.TRUE), true, v8Callback, syncCallback); } private V8CommandProcessor.V8HandlerCallback createScriptUpdateCallback( final UpdateCallback callback, final boolean previewOnly) { return new V8CommandCallbackBase() { @Override public void success(SuccessCommandResponse successResponse) { ChangeLiveBody body; try { body = successResponse.body().asChangeLiveBody(); } catch (JsonProtocolParseException e) { throw new RuntimeException(e); } LiveEditResult resultDescription = body.getResultDescription(); if (!previewOnly) { ScriptLoadCallback scriptCallback = new ScriptLoadCallback() { @Override public void failure(String message) { LOGGER.log(Level.SEVERE, "Failed to reload script after LiveEdit script update; " + message); } @Override public void success() { DebugEventListener listener = debugSession.getDebugEventListener(); if (listener != null) { listener.scriptContentChanged(ScriptImpl.this); } } }; V8Helper.reloadScriptAsync(debugSession, Collections.singletonList(getId()), scriptCallback, null); if (body.stepin_recommended() == Boolean.TRUE) { DebugContext debugContext = debugSession.getContextBuilder().getCurrentDebugContext(); if (debugContext == null) { // We may have already issued 'continue' since the moment that change live command // was sent so the context was dropped. Ignore this case. } else { debugContext.continueVm(DebugContext.StepAction.IN, 0, null); } } else { if (resultDescription != null && resultDescription.stack_modified()) { debugSession.recreateCurrentContext(); } } } if (callback != null) { callback.success(body.getChangeLog(), UpdateResultParser.wrapChangeDescription(resultDescription)); } } @Override public void failure(String message) { callback.failure(message); } }; } public static Long getScriptId(HandleManager handleManager, long scriptRef) { SomeHandle handle = handleManager.getHandle(scriptRef); if (handle == null) { return -1L; // not found } ScriptHandle scriptHandle; try { scriptHandle = handle.asScriptHandle(); } catch (JsonProtocolParseException e) { throw new RuntimeException(e); } return scriptHandle.id(); } }