All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.co.real_logic.sbe.generation.common.PrecedenceChecks Maven / Gradle / Ivy

Go to download

FIX/SBE - OSI layer 6 presentation for encoding and decoding application messages in binary format for low-latency applications.

The newest version!
/*
 * Copyright 2013-2024 Real Logic Limited.
 *
 * 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
 *
 * https://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 uk.co.real_logic.sbe.generation.common;

import uk.co.real_logic.sbe.ir.Token;

import java.util.ArrayList;
import java.util.List;
import java.util.OptionalInt;
import java.util.function.Function;
import java.util.stream.IntStream;

import static java.util.Objects.requireNonNull;
import static uk.co.real_logic.sbe.ir.GenerationUtil.collectFields;
import static uk.co.real_logic.sbe.ir.GenerationUtil.collectGroups;
import static uk.co.real_logic.sbe.ir.GenerationUtil.collectVarData;

/**
 * A factory for creating a {@link FieldPrecedenceModel} for a message from its IR tokens.
 */
public final class PrecedenceChecks
{
    private static final Function SELECT_LATEST_VERSION_ONLY = versions ->
    {
        final OptionalInt max = versions.max();
        return max.isPresent() ? IntStream.of(max.getAsInt()) : IntStream.empty();
    };

    private final Context context;

    private PrecedenceChecks(final Context context)
    {
        context.conclude();
        this.context = context;
    }

    /**
     * Creates a {@link FieldPrecedenceModel} for the given message tokens,
     * unless precedence checks are disabled, in which case {@code null} is returned.
     * 

* Only the latest version of the message is considered when creating the model. *

* * @param stateClassName the name of the generated class that models the state of the encoder. * @param msgTokens the tokens of the message. * @return a {@link FieldPrecedenceModel} for the given message tokens or {@code null} if precedence checks * are disabled. */ public FieldPrecedenceModel createEncoderModel( final String stateClassName, final List msgTokens) { return createModel(stateClassName, msgTokens, SELECT_LATEST_VERSION_ONLY); } /** * Creates a {@link FieldPrecedenceModel} for the given message tokens, * unless precedence checks are disabled, in which case {@code null} is returned. *

* All versions of the message are considered when creating the model. *

* * @param stateClassName the name of the generated class that models the state of the decoder. * @param msgTokens the tokens of the message. * @return a {@link FieldPrecedenceModel} for the given message tokens or {@code null} if precedence checks * are disabled. */ public FieldPrecedenceModel createDecoderModel( final String stateClassName, final List msgTokens) { return createModel(stateClassName, msgTokens, Function.identity()); } /** * Creates a {@link FieldPrecedenceModel} for the given message tokens, * unless precedence checks are disabled, in which case {@code null} is returned. *

* All versions of the message are considered when creating the model. *

* * @param stateClassName the name of the generated class that models the state of the codec. * @param msgTokens the tokens of the message. * @return a {@link FieldPrecedenceModel} for the given message tokens or {@code null} if precedence checks * are disabled. */ public FieldPrecedenceModel createCodecModel( final String stateClassName, final List msgTokens ) { return createModel(stateClassName, msgTokens, Function.identity()); } /** * Returns the {@link Context} describing how precedence checks should be generated. * * @return the {@link Context} describing how precedence checks should be generated. */ public Context context() { return context; } /** * Creates a new {@link PrecedenceChecks} instance. * * @param context the {@link Context} describing how precedence checks should be generated. * @return a new {@link PrecedenceChecks} instance. */ public static PrecedenceChecks newInstance(final Context context) { return new PrecedenceChecks(context); } private FieldPrecedenceModel createModel( final String stateClassName, final List tokens, final Function versionsSelector ) { if (context.shouldGeneratePrecedenceChecks()) { final Token msgToken = tokens.get(0); final List messageBody = tokens.subList(1, tokens.size() - 1); int i = 0; final List fields = new ArrayList<>(); i = collectFields(messageBody, i, fields); final List groups = new ArrayList<>(); i = collectGroups(messageBody, i, groups); final List varData = new ArrayList<>(); collectVarData(messageBody, i, varData); return FieldPrecedenceModel.newInstance( stateClassName, msgToken, fields, groups, varData, versionsSelector); } return null; } /** * The context describing how precedence checks should be generated. */ public static final class Context { private boolean shouldGeneratePrecedenceChecks; private String precedenceChecksFlagName = "SBE_ENABLE_PRECEDENCE_CHECKS"; private String precedenceChecksPropName = "sbe.enable.precedence.checks"; /** * Returns {@code true} if precedence checks should be generated; {@code false} otherwise. * * @return {@code true} if precedence checks should be generated; {@code false} otherwise. */ public boolean shouldGeneratePrecedenceChecks() { return shouldGeneratePrecedenceChecks; } /** * Sets whether field precedence checks should be generated. * * @param shouldGeneratePrecedenceChecks {@code true} if precedence checks should be generated; * {@code false} otherwise. * @return this {@link Context} instance. */ public Context shouldGeneratePrecedenceChecks(final boolean shouldGeneratePrecedenceChecks) { this.shouldGeneratePrecedenceChecks = shouldGeneratePrecedenceChecks; return this; } /** * Returns the name of the flag that can be used to enable precedence checks at runtime. * * @return the name of the flag that can be used to enable precedence checks at runtime. */ public String precedenceChecksFlagName() { return precedenceChecksFlagName; } /** * Sets the name of the flag that can be used to enable precedence checks at runtime. * * @param precedenceChecksFlagName the name of the flag that can be used to enable * precedence checks at runtime. * @return this {@link Context} instance. */ public Context precedenceChecksFlagName(final String precedenceChecksFlagName) { this.precedenceChecksFlagName = precedenceChecksFlagName; return this; } /** * Returns the name of the system property that can be used to enable precedence checks * at runtime. * * @return the name of the system property that can be used to enable precedence checks * at runtime. */ public String precedenceChecksPropName() { return precedenceChecksPropName; } /** * Sets the name of the system property that can be used to enable precedence checks * at runtime. * * @param precedenceChecksPropName the name of the system property that can be used to * enable precedence checks at runtime. * @return this {@link Context} instance. */ public Context precedenceChecksPropName(final String precedenceChecksPropName) { this.precedenceChecksPropName = precedenceChecksPropName; return this; } /** * Validates this {@link Context} instance. */ public void conclude() { requireNonNull(precedenceChecksFlagName, "precedenceChecksFlagName"); requireNonNull(precedenceChecksPropName, "precedenceChecksPropName"); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy