Code review comment: <!--thread_id:cc_143604148_t; commit:eea1f1cdc4b66118bbcf9a7d5b7e648e299c5464; resolved:1--> <!--section:context-quote--> > **tgroh** wrote: > Components will be used for the environment? Should this be piped through to the `toProto` call and commented in that call?  <!--section:body--> Yes, the components here and in maybe a hundred other places will need to be plumbed in order to add the environment. It is way beyond scope here - status quo is that we don't know what the Environment proto is going to look like and nothing plumbs it.

Code under review:
new ParDoLike() {
          @Override
          public SdkFunctionSpec translateDoFn(SdkComponents newComponents) {
            return toProto(parDo.getFn(), parDo.getMainOutputTag());
          }

          @Override
          public List<RunnerApi.Parameter> translateParameters() {
            List<RunnerApi.Parameter> parameters = new ArrayList<>();
            for (Parameter parameter : signature.processElement().extraParameters()) {
              Optional<RunnerApi.Parameter> protoParameter = toProto(parameter);
              if (protoParameter.isPresent()) {
                parameters.add(protoParameter.get());
              }
            }
            return parameters;
          }

          @Override
          public Map<String, SideInput> translateSideInputs(SdkComponents components) {
            Map<String, SideInput> sideInputs = new HashMap<>();
            for (PCollectionView<?> sideInput : parDo.getSideInputs()) {
              sideInputs.put(sideInput.getTagInternal().getId(), toProto(sideInput));
            }
            return sideInputs;
          }

          @Override
          public Map<String, RunnerApi.StateSpec> translateStateSpecs(SdkComponents components)
              throws IOException {
            Map<String, RunnerApi.StateSpec> stateSpecs = new HashMap<>();
            for (Map.Entry<String, StateDeclaration> state :
                signature.stateDeclarations().entrySet()) {
              RunnerApi.StateSpec spec =
                  toProto(getStateSpecOrCrash(state.getValue(), doFn), components);
              stateSpecs.put(state.getKey(), spec);
            }
            return stateSpecs;
          }

          @Override
          public Map<String, RunnerApi.TimerSpec> translateTimerSpecs(SdkComponents newComponents) {
            Map<String, RunnerApi.TimerSpec> timerSpecs = new HashMap<>();
            for (Map.Entry<String, TimerDeclaration> timer :
                signature.timerDeclarations().entrySet()) {
              RunnerApi.TimerSpec spec = toProto(getTimerSpecOrCrash(timer.getValue(), doFn));
              timerSpecs.put(timer.getKey(), spec);
            }
            return timerSpecs;
          }

          @Override
          public boolean isSplittable() {
            return signature.processElement().isSplittable();
          }
        },

Line commented on: public SdkFunctionSpec translateDoFn(SdkComponents newComponents) {

Revised code:
new ParDoLike() {
          @Override
          public SdkFunctionSpec translateDoFn(SdkComponents newComponents) {
            return toProto(parDo.getFn(), parDo.getMainOutputTag());
          }

          @Override
          public List<RunnerApi.Parameter> translateParameters() {
            List<RunnerApi.Parameter> parameters = new ArrayList<>();
            for (Parameter parameter : signature.processElement().extraParameters()) {
              Optional<RunnerApi.Parameter> protoParameter = toProto(parameter);
              if (protoParameter.isPresent()) {
                parameters.add(protoParameter.get());
              }
            }
            return parameters;
          }

          @Override
          public Map<String, SideInput> translateSideInputs(SdkComponents components) {
            Map<String, SideInput> sideInputs = new HashMap<>();
            for (PCollectionView<?> sideInput : parDo.getSideInputs()) {
              sideInputs.put(sideInput.getTagInternal().getId(), toProto(sideInput));
            }
            return sideInputs;
          }

          @Override
          public Map<String, RunnerApi.StateSpec> translateStateSpecs(SdkComponents components)
              throws IOException {
            Map<String, RunnerApi.StateSpec> stateSpecs = new HashMap<>();
            for (Map.Entry<String, StateDeclaration> state :
                signature.stateDeclarations().entrySet()) {
              RunnerApi.StateSpec spec =
                  toProto(getStateSpecOrCrash(state.getValue(), doFn), components);
              stateSpecs.put(state.getKey(), spec);
            }
            return stateSpecs;
          }

          @Override
          public Map<String, RunnerApi.TimerSpec> translateTimerSpecs(SdkComponents newComponents) {
            Map<String, RunnerApi.TimerSpec> timerSpecs = new HashMap<>();
            for (Map.Entry<String, TimerDeclaration> timer :
                signature.timerDeclarations().entrySet()) {
              RunnerApi.TimerSpec spec = toProto(getTimerSpecOrCrash(timer.getValue(), doFn));
              timerSpecs.put(timer.getKey(), spec);
            }
            return timerSpecs;
          }

          @Override
          public boolean isSplittable() {
            return signature.processElement().isSplittable();
          }
        }